Skip to content

Commit 7b57c21

Browse files
Merge pull request #4921 from swiftwasm/main
[pull] swiftwasm from main
2 parents dedf920 + 9e07e69 commit 7b57c21

File tree

176 files changed

+1609
-816
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

176 files changed

+1609
-816
lines changed

SwiftCompilerSources/Sources/Optimizer/DataStructures/FunctionUses.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,15 @@ struct FunctionUses {
134134

135135
for witnessTable in context.witnessTables {
136136
for entry in witnessTable.entries {
137-
if entry.kind == .method, let f = entry.methodFunction {
137+
if entry.kind == .Method, let f = entry.methodFunction {
138138
markUnknown(f)
139139
}
140140
}
141141
}
142142

143143
for witnessTable in context.defaultWitnessTables {
144144
for entry in witnessTable.entries {
145-
if entry.kind == .method, let f = entry.methodFunction {
145+
if entry.kind == .Method, let f = entry.methodFunction {
146146
markUnknown(f)
147147
}
148148
}

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeEffects.swift

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,11 @@ let computeEffects = FunctionPass(name: "compute-effects", {
3030
(function: Function, context: PassContext) in
3131
var argsWithDefinedEffects = getArgIndicesWithDefinedEffects(of: function)
3232

33-
struct IgnoreRecursiveCallVisitor : EscapeInfoVisitor {
33+
struct IgnoreRecursiveCallVisitor : EscapeVisitor {
3434
func visitUse(operand: Operand, path: EscapePath) -> UseResult {
3535
return isOperandOfRecursiveCall(operand) ? .ignore : .continueWalk
3636
}
3737
}
38-
var escapeInfo = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: IgnoreRecursiveCallVisitor())
3938
var newEffects = Stack<ArgumentEffect>(context)
4039
let returnInst = function.returnInstruction
4140

@@ -47,7 +46,8 @@ let computeEffects = FunctionPass(name: "compute-effects", {
4746
if argsWithDefinedEffects.contains(arg.index) { continue }
4847

4948
// First check: is the argument (or a projected value of it) escaping at all?
50-
if !escapeInfo.isEscapingWhenWalkingDown(object: arg, path: SmallProjectionPath(.anything)) {
49+
if !arg.at(.anything).isEscapingWhenWalkingDown(using: IgnoreRecursiveCallVisitor(),
50+
context) {
5151
newEffects.push(ArgumentEffect(.notEscaping, argumentIndex: arg.index, pathPattern: SmallProjectionPath(.anything)))
5252
continue
5353
}
@@ -78,7 +78,7 @@ func addArgEffects(_ arg: FunctionArgument, argPath ap: SmallProjectionPath,
7878
// containing one or more references.
7979
let argPath = arg.type.isClass ? ap : ap.push(.anyValueFields)
8080

81-
struct ArgEffectsVisitor : EscapeInfoVisitor {
81+
struct ArgEffectsVisitor : EscapeVisitorWithResult {
8282
enum EscapeDestination {
8383
case notSet
8484
case toReturn(SmallProjectionPath)
@@ -131,8 +131,8 @@ func addArgEffects(_ arg: FunctionArgument, argPath ap: SmallProjectionPath,
131131
}
132132
}
133133

134-
var walker = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: ArgEffectsVisitor())
135-
if walker.isEscapingWhenWalkingDown(object: arg, path: argPath) {
134+
guard let result = arg.at(argPath).visitByWalkingDown(using: ArgEffectsVisitor(),
135+
context) else {
136136
return false
137137
}
138138

@@ -142,7 +142,7 @@ func addArgEffects(_ arg: FunctionArgument, argPath ap: SmallProjectionPath,
142142
}
143143

144144
let effect: ArgumentEffect
145-
switch walker.visitor.result {
145+
switch result {
146146
case .notSet:
147147
effect = ArgumentEffect(.notEscaping, argumentIndex: arg.index, pathPattern: argPath)
148148
case .toReturn(let toPath):
@@ -200,7 +200,7 @@ private
200200
func isExclusiveEscapeToReturn(fromArgument: Argument, fromPath: SmallProjectionPath,
201201
toPath: SmallProjectionPath,
202202
returnInst: ReturnInst, _ context: PassContext) -> Bool {
203-
struct IsExclusiveReturnEscapeVisitor : EscapeInfoVisitor {
203+
struct IsExclusiveReturnEscapeVisitor : EscapeVisitor {
204204
let fromArgument: Argument
205205
let fromPath: SmallProjectionPath
206206
let toPath: SmallProjectionPath
@@ -228,14 +228,13 @@ func isExclusiveEscapeToReturn(fromArgument: Argument, fromPath: SmallProjection
228228
}
229229
}
230230
let visitor = IsExclusiveReturnEscapeVisitor(fromArgument: fromArgument, fromPath: fromPath, toPath: toPath)
231-
var walker = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: visitor)
232-
return !walker.isEscaping(object: returnInst.operand, path: toPath)
231+
return !returnInst.operand.at(toPath).isEscaping(using: visitor, context)
233232
}
234233

235234
private
236235
func isExclusiveEscapeToArgument(fromArgument: Argument, fromPath: SmallProjectionPath,
237236
toArgumentIndex: Int, toPath: SmallProjectionPath, _ context: PassContext) -> Bool {
238-
struct IsExclusiveArgumentEscapeVisitor : EscapeInfoVisitor {
237+
struct IsExclusiveArgumentEscapeVisitor : EscapeVisitor {
239238
let fromArgument: Argument
240239
let fromPath: SmallProjectionPath
241240
let toArgumentIndex: Int
@@ -253,8 +252,7 @@ func isExclusiveEscapeToArgument(fromArgument: Argument, fromPath: SmallProjecti
253252
}
254253
let visitor = IsExclusiveArgumentEscapeVisitor(fromArgument: fromArgument, fromPath: fromPath,
255254
toArgumentIndex: toArgumentIndex, toPath: toPath)
256-
var walker = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: visitor)
257255
let toArg = fromArgument.function.arguments[toArgumentIndex]
258-
return !walker.isEscaping(object: toArg, path: toPath)
256+
return !toArg.at(toPath).isEscapingWhenWalkingDown(using: visitor, context)
259257
}
260258

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/StackPromotion.swift

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,8 @@ func tryPromoteAlloc(_ allocRef: AllocRefInstBase,
7575
if allocRef.isObjC || allocRef.canAllocOnStack {
7676
return false
7777
}
78-
struct DefaultVisitor : EscapeInfoVisitor {}
79-
var ei = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: DefaultVisitor())
80-
8178
// The most important check: does the object escape the current function?
82-
if ei.isEscaping(object:allocRef) {
79+
if allocRef.isEscaping(context) {
8380
return false
8481
}
8582

@@ -196,21 +193,19 @@ func tryPromoteAlloc(_ allocRef: AllocRefInstBase,
196193
private func getDominatingBlockOfAllUsePoints(context: PassContext,
197194
_ value: SingleValueInstruction,
198195
domTree: DominatorTree) -> BasicBlock {
199-
struct Visitor : EscapeInfoVisitor {
200-
var dominatingBlock: BasicBlock
196+
struct FindDominatingBlock : EscapeVisitorWithResult {
197+
var result: BasicBlock
201198
let domTree: DominatorTree
202199
mutating func visitUse(operand: Operand, path: EscapePath) -> UseResult {
203200
let defBlock = operand.value.definingBlock
204-
if defBlock.dominates(dominatingBlock, domTree) {
205-
dominatingBlock = defBlock
201+
if defBlock.dominates(result, domTree) {
202+
result = defBlock
206203
}
207204
return .continueWalk
208205
}
209206
}
210207

211-
var walker = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: Visitor(dominatingBlock: value.block, domTree: domTree))
212-
_ = walker.isEscaping(object: value)
213-
return walker.visitor.dominatingBlock
208+
return value.visit(using: FindDominatingBlock(result: value.block, domTree: domTree), context)!
214209
}
215210

216211

@@ -219,11 +214,13 @@ func computeInnerAndOuterLiferanges(instruction: SingleValueInstruction, in domB
219214
/// All uses which are dominated by the `innerInstRange`s begin-block are included
220215
/// in both, the `innerInstRange` and the `outerBlockRange`.
221216
/// All _not_ dominated uses are only included in the `outerBlockRange`.
222-
struct Visitor : EscapeInfoVisitor {
217+
struct Visitor : EscapeVisitorWithResult {
223218
var innerRange: InstructionRange
224219
var outerBlockRange: BasicBlockRange
225220
let domTree: DominatorTree
226221

222+
var result: (InstructionRange, BasicBlockRange) { (innerRange, outerBlockRange) }
223+
227224
init(instruction: Instruction, domBlock: BasicBlock, domTree: DominatorTree, context: PassContext) {
228225
innerRange = InstructionRange(begin: instruction, context)
229226
outerBlockRange = BasicBlockRange(begin: domBlock, context)
@@ -245,7 +242,7 @@ func computeInnerAndOuterLiferanges(instruction: SingleValueInstruction, in domB
245242
outerBlockRange.insert(defBlock)
246243

247244
// We need to explicitly add predecessor blocks of phi-arguments becaues they
248-
// are not necesesarily visited by `EscapeInfo.walkDown`.
245+
// are not necesesarily visited during the down-walk in `isEscaping()`.
249246
// This is important for the special case where there is a back-edge from the
250247
// inner range to the inner rage's begin-block:
251248
//
@@ -261,16 +258,11 @@ func computeInnerAndOuterLiferanges(instruction: SingleValueInstruction, in domB
261258
return .continueWalk
262259
}
263260
}
264-
265-
var walker = EscapeInfo(calleeAnalysis: context.calleeAnalysis,
266-
visitor: Visitor(
267-
instruction: instruction,
268-
domBlock: domBlock,
269-
domTree: domTree,
270-
context: context
271-
))
272-
_ = walker.isEscaping(object: instruction)
273-
return (walker.visitor.innerRange, walker.visitor.outerBlockRange)
261+
262+
return instruction.visit(using: Visitor(instruction: instruction,
263+
domBlock: domBlock,
264+
domTree: domTree,
265+
context: context), context)!
274266
}
275267

276268
private extension BasicBlockRange {

SwiftCompilerSources/Sources/Optimizer/ModulePasses/StackProtection.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ private struct StackProtectionOptimization {
124124
mustFixStackNesting: inout Bool, _ context: PassContext) {
125125

126126
// `withUnsafeTemporaryAllocation(of:capacity:_:)` is compiled to a `builtin "stackAlloc"`.
127-
if let bi = instruction as? BuiltinInst, bi.id == .stackAlloc {
127+
if let bi = instruction as? BuiltinInst, bi.id == .StackAlloc {
128128
function.setNeedsStackProtection(context)
129129
return
130130
}
@@ -332,7 +332,7 @@ private struct StackProtectionOptimization {
332332
/// Moves the value of a `beginAccess` to a temporary stack location, if possible.
333333
private func moveToTemporary(scope beginAccess: BeginAccessInst, mustFixStackNesting: inout Bool,
334334
_ context: PassContext) {
335-
if beginAccess.accessKind != .modify {
335+
if beginAccess.accessKind != .Modify {
336336
// We can only move from a `modify` access.
337337
// Also, read-only accesses shouldn't be subject to buffer overflows (because
338338
// no one should ever write to such a storage).

SwiftCompilerSources/Sources/Optimizer/TestPasses/AccessDumper.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ let accessDumper = FunctionPass(name: "dump-access", {
5050

5151
private struct AccessStoragePathVisitor : AccessStoragePathWalker {
5252
var walkUpCache = WalkerCache<Path>()
53-
mutating func visit(access: AccessStoragePath) {
54-
print(" Storage: \(access.storage)")
55-
print(" Path: \"\(access.path)\"")
53+
mutating func visit(accessStoragePath: ProjectedValue) {
54+
print(" Storage: \(accessStoragePath.value)")
55+
print(" Path: \"\(accessStoragePath.path)\"")
5656
}
5757
}
5858

SwiftCompilerSources/Sources/Optimizer/TestPasses/EscapeInfoDumper.swift

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ let escapeInfoDumper = FunctionPass(name: "dump-escape-info", {
2222

2323
print("Escape information for \(function.name):")
2424

25-
struct Visitor : EscapeInfoVisitor {
26-
var results: Set<String> = Set()
25+
struct Visitor : EscapeVisitorWithResult {
26+
var result: Set<String> = Set()
2727

2828
mutating func visitUse(operand: Operand, path: EscapePath) -> UseResult {
2929
if operand.instruction is ReturnInst {
30-
results.insert("return[\(path.projectionPath)]")
30+
result.insert("return[\(path.projectionPath)]")
3131
return .ignore
3232
}
3333
return .continueWalk
@@ -37,7 +37,7 @@ let escapeInfoDumper = FunctionPass(name: "dump-escape-info", {
3737
guard let arg = def as? FunctionArgument else {
3838
return .continueWalkUp
3939
}
40-
results.insert("arg\(arg.index)[\(path.projectionPath)]")
40+
result.insert("arg\(arg.index)[\(path.projectionPath)]")
4141
return .walkDown
4242
}
4343
}
@@ -46,19 +46,17 @@ let escapeInfoDumper = FunctionPass(name: "dump-escape-info", {
4646
for inst in function.instructions {
4747
if let allocRef = inst as? AllocRefInst {
4848

49-
var walker = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: Visitor())
50-
let escapes = walker.isEscaping(object: allocRef)
51-
let results = walker.visitor.results
52-
53-
let res: String
54-
if escapes {
55-
res = "global"
56-
} else if results.isEmpty {
57-
res = " - "
49+
let resultStr: String
50+
if let result = allocRef.visit(using: Visitor(), context) {
51+
if result.isEmpty {
52+
resultStr = " - "
53+
} else {
54+
resultStr = Array(result).sorted().joined(separator: ",")
55+
}
5856
} else {
59-
res = Array(results).sorted().joined(separator: ",")
57+
resultStr = "global"
6058
}
61-
print("\(res): \(allocRef)")
59+
print("\(resultStr): \(allocRef)")
6260
}
6361
}
6462
print("End function \(function.name)\n")
@@ -90,7 +88,7 @@ let addressEscapeInfoDumper = FunctionPass(name: "dump-addr-escape-info", {
9088
}
9189
}
9290

93-
struct Visitor : EscapeInfoVisitor {
91+
struct Visitor : EscapeVisitor {
9492
let apply: Instruction
9593
mutating func visitUse(operand: Operand, path: EscapePath) -> UseResult {
9694
let user = operand.instruction
@@ -111,13 +109,14 @@ let addressEscapeInfoDumper = FunctionPass(name: "dump-addr-escape-info", {
111109
for apply in applies {
112110
let path = AliasAnalysis.getPtrOrAddressPath(for: value)
113111

114-
var escapeInfo = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: Visitor(apply: apply))
115-
let escaping = escapeInfo.isEscaping(addressesOf: value, path: path)
116-
print(" \(escaping ? "==>" : "- ") \(apply)")
112+
if value.at(path).isAddressEscaping(using: Visitor(apply: apply), context) {
113+
print(" ==> \(apply)")
114+
} else {
115+
print(" - \(apply)")
116+
}
117117
}
118118
}
119119

120-
var eaa = EscapeAliasAnalysis(calleeAnalysis: context.calleeAnalysis)
121120
// test `canReferenceSameField` for each pair of `fix_lifetime`.
122121
if !valuesToCheck.isEmpty {
123122
for lhsIdx in 0..<(valuesToCheck.count - 1) {
@@ -127,9 +126,14 @@ let addressEscapeInfoDumper = FunctionPass(name: "dump-addr-escape-info", {
127126
let rhs = valuesToCheck[rhsIdx]
128127
print(lhs)
129128
print(rhs)
130-
if eaa.canReferenceSameField(
131-
lhs, path: AliasAnalysis.getPtrOrAddressPath(for: lhs),
132-
rhs, path: AliasAnalysis.getPtrOrAddressPath(for: rhs)) {
129+
130+
let projLhs = lhs.at(AliasAnalysis.getPtrOrAddressPath(for: lhs))
131+
let projRhs = rhs.at(AliasAnalysis.getPtrOrAddressPath(for: rhs))
132+
let mayAlias = projLhs.canAddressAlias(with: projRhs, context)
133+
assert(mayAlias == projRhs.canAddressAlias(with: projLhs, context),
134+
"canAddressAlias(with:) must be symmetric")
135+
136+
if mayAlias {
133137
print("may alias")
134138
} else {
135139
print("no alias")

0 commit comments

Comments
 (0)