Skip to content

Commit 3bba7ca

Browse files
committed
Swift SIL: add var Function.instructions
To be used to iterate over all instructions in a function without the need of two loops - one for blocks and one for instructions.
1 parent fd4e98a commit 3bba7ca

File tree

7 files changed

+68
-77
lines changed

7 files changed

+68
-77
lines changed

SwiftCompilerSources/Sources/Optimizer/DataStructures/Set.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,9 @@ struct InstructionSet : CustomStringConvertible, CustomReflectable {
150150
var description: String {
151151
let function = NodeSet_getFunction(bridged).function
152152
var d = "{\n"
153-
for block in function.blocks {
154-
for inst in block.instructions {
155-
if contains(inst) {
156-
d += inst.description
157-
}
153+
for inst in function.instructions {
154+
if contains(inst) {
155+
d += inst.description
158156
}
159157
}
160158
d += "}\n"

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/AssumeSingleThreaded.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ import SIL
2929

3030
let assumeSingleThreadedPass = FunctionPass(
3131
name: "sil-assume-single-threaded", { function, context in
32-
for block in function.blocks {
33-
for inst in block.instructions {
34-
guard let rcInst = inst as? RefCountingInst else { continue }
32+
for inst in function.instructions {
33+
guard let rcInst = inst as? RefCountingInst else { continue }
3534

36-
rcInst.setAtomicity(isAtomic: false, context)
37-
}
35+
rcInst.setAtomicity(isAtomic: false, context)
3836
}
3937
}
4038
)

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/EscapeInfoDumper.swift

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

4545

46-
for block in function.blocks {
47-
for inst in block.instructions {
48-
if let allocRef = inst as? AllocRefInst {
49-
50-
var walker = EscapeInfo(calleeAnalysis: context.calleeAnalysis, visitor: Visitor())
51-
let escapes = walker.isEscaping(object: allocRef)
52-
let results = walker.visitor.results
53-
54-
let res: String
55-
if escapes {
56-
res = "global"
57-
} else if results.isEmpty {
58-
res = " - "
59-
} else {
60-
res = Array(results).sorted().joined(separator: ",")
61-
}
62-
print("\(res): \(allocRef)")
46+
for inst in function.instructions {
47+
if let allocRef = inst as? AllocRefInst {
48+
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 = " - "
58+
} else {
59+
res = Array(results).sorted().joined(separator: ",")
6360
}
61+
print("\(res): \(allocRef)")
6462
}
6563
}
6664
print("End function \(function.name)\n")
@@ -81,16 +79,14 @@ let addressEscapeInfoDumper = FunctionPass(name: "dump-addr-escape-info", {
8179
var valuesToCheck = [Value]()
8280
var applies = [Instruction]()
8381

84-
for block in function.blocks {
85-
for inst in block.instructions {
86-
switch inst {
87-
case let fli as FixLifetimeInst:
88-
valuesToCheck.append(fli.operand)
89-
case is FullApplySite:
90-
applies.append(inst)
91-
default:
92-
break
93-
}
82+
for inst in function.instructions {
83+
switch inst {
84+
case let fli as FixLifetimeInst:
85+
valuesToCheck.append(fli.operand)
86+
case is FullApplySite:
87+
applies.append(inst)
88+
default:
89+
break
9490
}
9591
}
9692

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ObjCBridgingOptimization.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,10 @@ let objCBridgingOptimization = FunctionPass(name: "objc-bridging-opt", {
4848
}
4949

5050
// Now try to optimize non-optional and optional -> non-optional bridging.
51-
for block in function.blocks {
52-
for inst in block.instructions {
53-
if let apply = inst as? ApplyInst {
54-
if !optimizeNonOptionalBridging(apply, context) {
55-
return
56-
}
51+
for inst in function.instructions {
52+
if let apply = inst as? ApplyInst {
53+
if !optimizeNonOptionalBridging(apply, context) {
54+
return
5755
}
5856
}
5957
}

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/RangeDumper.swift

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,22 @@ let rangeDumper = FunctionPass(name: "dump-ranges", {
2525
var outs = Stack<Instruction>(context)
2626
defer { outs.deinitialize() }
2727

28-
for block in function.blocks {
29-
for inst in block.instructions {
30-
if let sli = inst as? StringLiteralInst {
31-
switch sli.string {
32-
case "begin":
33-
precondition(begin == nil, "more than one begin instruction")
34-
begin = sli
35-
case "end":
36-
ends.append(sli)
37-
case "interior":
38-
interiors.append(sli)
39-
case "inside":
40-
ins.append(sli)
41-
case "outside":
42-
outs.append(sli)
43-
default:
44-
break
45-
}
28+
for inst in function.instructions {
29+
if let sli = inst as? StringLiteralInst {
30+
switch sli.string {
31+
case "begin":
32+
precondition(begin == nil, "more than one begin instruction")
33+
begin = sli
34+
case "end":
35+
ends.append(sli)
36+
case "interior":
37+
interiors.append(sli)
38+
case "inside":
39+
ins.append(sli)
40+
case "outside":
41+
outs.append(sli)
42+
default:
43+
break
4644
}
4745
}
4846
}

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/StackPromotion.swift

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,21 @@ let stackPromotion = FunctionPass(name: "stack-promotion", {
4444
let deadEndBlocks = context.deadEndBlocks
4545

4646
var changed = false
47-
for block in function.blocks {
48-
for inst in block.instructions {
49-
if let ar = inst as? AllocRefInstBase {
50-
if deadEndBlocks.isDeadEnd(block) {
51-
// Don't stack promote any allocation inside a code region which ends up
52-
// in a no-return block. Such allocations may missing their final release.
53-
// We would insert the deallocation too early, which may result in a
54-
// use-after-free problem.
55-
continue
56-
}
57-
if !context.continueWithNextSubpassRun(for: ar) {
58-
break
59-
}
47+
for inst in function.instructions {
48+
if let ar = inst as? AllocRefInstBase {
49+
if deadEndBlocks.isDeadEnd(ar.block) {
50+
// Don't stack promote any allocation inside a code region which ends up
51+
// in a no-return block. Such allocations may missing their final release.
52+
// We would insert the deallocation too early, which may result in a
53+
// use-after-free problem.
54+
continue
55+
}
56+
if !context.continueWithNextSubpassRun(for: ar) {
57+
break
58+
}
6059

61-
if tryPromoteAlloc(ar, deadEndBlocks, context) {
62-
changed = true
63-
}
60+
if tryPromoteAlloc(ar, deadEndBlocks, context) {
61+
changed = true
6462
}
6563
}
6664
}

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ final public class Function : CustomStringConvertible, HasShortDescription {
4141
entryBlock.arguments.lazy.map { $0 as! FunctionArgument }
4242
}
4343

44+
/// All instructions of all blocks.
45+
public var instructions: LazySequence<FlattenSequence<LazyMapSequence<List<BasicBlock>, List<Instruction>>>> {
46+
blocks.lazy.flatMap { $0.instructions }
47+
}
48+
4449
public var numIndirectResultArguments: Int {
4550
SILFunction_numIndirectResultArguments(bridged)
4651
}

0 commit comments

Comments
 (0)