Skip to content

Commit e8d408d

Browse files
committed
libswift: implement SILCombine's global_value optimization as instruction pass in libswift.
But keeping the old visit function as legacy
1 parent 1010f1e commit e8d408d

File tree

7 files changed

+69
-2
lines changed

7 files changed

+69
-2
lines changed

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ PASS(PruneVTables, "prune-vtables",
421421
"Mark class methods that do not require vtable dispatch")
422422
PASS_RANGE(AllPasses, AADumper, PruneVTables)
423423

424+
SWIFT_INSTRUCTION_PASS_WITH_LEGACY(GlobalValueInst, "simplify-global_value")
425+
424426
#undef IRGEN_PASS
425427
#undef SWIFT_FUNCTION_PASS
426428
#undef SWIFT_FUNCTION_PASS_WITH_LEGACY

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,11 +326,12 @@ class SILCombiner :
326326

327327
SILInstruction *visitMarkDependenceInst(MarkDependenceInst *MDI);
328328
SILInstruction *visitClassifyBridgeObjectInst(ClassifyBridgeObjectInst *CBOI);
329-
SILInstruction *visitGlobalValueInst(GlobalValueInst *globalValue);
330329
SILInstruction *visitConvertFunctionInst(ConvertFunctionInst *CFI);
331330
SILInstruction *
332331
visitConvertEscapeToNoEscapeInst(ConvertEscapeToNoEscapeInst *Cvt);
333332

333+
SILInstruction *legacyVisitGlobalValueInst(GlobalValueInst *globalValue);
334+
334335
#define PASS(ID, TAG, DESCRIPTION)
335336
#define SWIFT_FUNCTION_PASS(ID, TAG, DESCRIPTION)
336337
#define SWIFT_INSTRUCTION_PASS(INST, TAG) \

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2312,7 +2312,7 @@ static bool checkGlobalValueUsers(SILValue val,
23122312
}
23132313

23142314
SILInstruction *
2315-
SILCombiner::visitGlobalValueInst(GlobalValueInst *globalValue) {
2315+
SILCombiner::legacyVisitGlobalValueInst(GlobalValueInst *globalValue) {
23162316
// Delete all reference count instructions on a global_value if the only other
23172317
// users are projections (ref_element_addr and ref_tail_addr).
23182318
SmallVector<SILInstruction *, 8> toDelete;

libswift/Sources/Optimizer/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@
99
add_libswift_module(Optimizer
1010
DEPENDS SIL)
1111

12+
add_subdirectory(InstructionPasses)
1213
add_subdirectory(PassManager)
1314
add_subdirectory(FunctionPasses)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This source file is part of the Swift.org open source project
2+
#
3+
# Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
4+
# Licensed under Apache License v2.0 with Runtime Library Exception
5+
#
6+
# See http://swift.org/LICENSE.txt for license information
7+
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
8+
9+
libswift_sources(Optimizer
10+
SimplifyGlobalValue.swift)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===--- SimplifyGlobalValue.swift - Simplify global_value instruction ----===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SIL
14+
15+
let simplifyGlobalValuePass = InstructionPass<GlobalValueInst>(
16+
name: "simplify-global_value", {
17+
(globalValue: GlobalValueInst, context: InstructionPassContext) in
18+
19+
var users = StackList<Instruction>(context)
20+
if checkUsers(of: globalValue, users: &users) {
21+
while let inst = users.pop() {
22+
context.erase(instruction: inst)
23+
}
24+
} else {
25+
users.removeAll()
26+
}
27+
})
28+
29+
/// Returns true if reference counting and debug_value users of a global_value
30+
/// can be deleted.
31+
private func checkUsers(of val: Value, users: inout StackList<Instruction>) -> Bool {
32+
for use in val.uses {
33+
let user = use.instruction
34+
if user is RefCountingInst || user is DebugValueInst {
35+
users.push(user)
36+
continue
37+
}
38+
if let upCast = user as? UpcastInst {
39+
if !checkUsers(of: upCast, users: &users) {
40+
return false
41+
}
42+
continue
43+
}
44+
// Projection instructions don't access the object header, so they don't
45+
// prevent deleting reference counting instructions.
46+
if user is RefElementAddrInst || user is RefTailAddrInst {
47+
continue
48+
}
49+
return false
50+
}
51+
return true
52+
}

libswift/Sources/Optimizer/PassManager/PassRegistration.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ private func registerPass<InstType: Instruction>(
3838
private func registerSwiftPasses() {
3939
registerPass(silPrinterPass, { silPrinterPass.run($0) })
4040
registerPass(mergeCondFailsPass, { mergeCondFailsPass.run($0) })
41+
registerPass(simplifyGlobalValuePass, { simplifyGlobalValuePass.run($0) })
4142
}

0 commit comments

Comments
 (0)