Skip to content

Commit 54a738b

Browse files
committed
Merge branch 'main' into smooth_operator
2 parents 3eb2b1c + 840316a commit 54a738b

File tree

693 files changed

+10845
-6155
lines changed

Some content is hidden

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

693 files changed

+10845
-6155
lines changed

CMakeLists.txt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,7 @@ set(SWIFT_TOOLS_ENABLE_LTO OFF CACHE STRING "Build Swift tools with LTO. One
192192
option only affects the tools that run on the host (the compiler), and has
193193
no effect on the target libraries (the standard library and the runtime).")
194194

195-
# NOTE: We do not currently support building the swift compiler modules with the Xcode generator.
196-
cmake_dependent_option(BOOTSTRAPPING_MODE [=[
195+
option(BOOTSTRAPPING_MODE [=[
197196
How to build the swift compiler modules. Possible values are
198197
OFF: build without swift modules
199198
HOSTTOOLS: build with a pre-installed toolchain
@@ -204,7 +203,7 @@ How to build the swift compiler modules. Possible values are
204203
`SWIFT_NATIVE_SWIFT_TOOLS_PATH` (non-Darwin only)
205204
CROSSCOMPILE-WITH-HOSTLIBS: build with a bootstrapping-with-hostlibs compiled
206205
compiler, provided in `SWIFT_NATIVE_SWIFT_TOOLS_PATH`
207-
]=] OFF "NOT CMAKE_GENERATOR STREQUAL \"Xcode\"" OFF)
206+
]=] OFF)
208207

209208
# The following only works with the Ninja generator in CMake >= 3.0.
210209
set(SWIFT_PARALLEL_LINK_JOBS "" CACHE STRING
@@ -530,7 +529,12 @@ include(CMakePushCheckState)
530529

531530
# Print out path and version of any installed commands
532531
message(STATUS "CMake (${CMAKE_COMMAND}) Version: ${CMAKE_VERSION}")
533-
execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} --version
532+
if(XCODE)
533+
set(version_flag -version)
534+
else()
535+
set(version_flag --version)
536+
endif()
537+
execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} ${version_flag}
534538
OUTPUT_VARIABLE _CMAKE_MAKE_PROGRAM_VERSION
535539
OUTPUT_STRIP_TRAILING_WHITESPACE)
536540
message(STATUS "CMake Make Program (${CMAKE_MAKE_PROGRAM}) Version: ${_CMAKE_MAKE_PROGRAM_VERSION}")
@@ -1110,8 +1114,6 @@ if(SWIFT_INCLUDE_TOOLS)
11101114
# SwiftCompilerSources must come before "tools".
11111115
# It adds swift module names to the global property "swift_compiler_modules"
11121116
# which is used in add_swift_host_tool for the lldb workaround.
1113-
#
1114-
# NOTE: We do not currently support SwiftCompilerSources with the Xcode generator.
11151117
add_subdirectory(SwiftCompilerSources)
11161118

11171119
# Always include this after including stdlib/!

SwiftCompilerSources/CMakeLists.txt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ function(add_swift_compiler_modules_library name)
8989
set(sdk_option "")
9090

9191
if(SWIFT_HOST_VARIANT_SDK IN_LIST SWIFT_DARWIN_PLATFORMS)
92-
set(deployment_version "10.15") # TODO: once #38675 lands, replace this with
93-
# set(deployment_version "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}")
92+
set(deployment_version "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_DEPLOYMENT_VERSION}")
9493
set(sdk_option "-sdk" "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}")
9594
if(${BOOTSTRAPPING_MODE} STREQUAL "CROSSCOMPILE-WITH-HOSTLIBS")
9695
# Let the cross-compiled compile don't pick up the compiled stdlib by providing
@@ -120,7 +119,10 @@ function(add_swift_compiler_modules_library name)
120119
if (dependencies)
121120
foreach(dep_module ${dependencies})
122121
if (DEFINED "${dep_module}_dep_target")
123-
list(APPEND deps "${${dep_module}_dep_target}")
122+
# We have to add the module target for the ordering dependency
123+
# and the output file for the file dependency (otherwise the dependent
124+
# module wouldn't be rebuilt if the current module changes)
125+
list(APPEND deps "${${dep_module}_dep_target}" "${build_dir}/${dep_module}.o")
124126
else()
125127
message(FATAL_ERROR "module dependency ${module} -> ${dep_module} not found. Make sure to add modules in dependency order")
126128
endif()
@@ -158,6 +160,15 @@ function(add_swift_compiler_modules_library name)
158160
add_dependencies(${name} ${all_module_targets})
159161
set_target_properties(${name} PROPERTIES LINKER_LANGUAGE CXX)
160162
set_property(GLOBAL APPEND PROPERTY SWIFT_BUILDTREE_EXPORTS ${name})
163+
164+
# Xcode does not compile libraries that contain only object files.
165+
# Therefore, it fails to create the static library. As a workaround,
166+
# we add a dummy script phase to the target.
167+
if (XCODE)
168+
add_custom_command(TARGET ${name} POST_BUILD
169+
COMMAND ""
170+
COMMENT "Dummy script phase to force building this target")
171+
endif()
161172
endfunction()
162173

163174

SwiftCompilerSources/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,6 @@ Some performance considerations:
169169

170170
* Memory is managed on the C++ side. On the Swift side, SIL objects are treated as "immortal" objects, which avoids (most of) ARC overhead. ARC runtime functions are still being called, but no atomic reference counting operations are done. In future we could add a compiler feature to mark classes as immortal to avoid the runtime calls at all.
171171

172-
* Minimizing memory allocations by using data structures which are malloc-free. For example `StackList` can be used in optimizations to implement work lists without any memory allocations. (Not yet done: `BasicBlockSet`, `BasicBlockData`)
172+
* Minimizing memory allocations by using data structures which are malloc-free, e.g. `Stack`
173173

174174
* The Swift modules are compiled with `-cross-module-optimization`. This enables the compiler to optimize the Swift code across module boundaries.

SwiftCompilerSources/Sources/Optimizer/Analysis/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@
88

99
swift_compiler_sources(Optimizer
1010
AliasAnalysis.swift
11-
CalleeAnalysis.swift)
11+
CalleeAnalysis.swift
12+
DeadEndBlocksAnalysis.swift
13+
DominatorTree.swift
14+
PostDominatorTree.swift)

SwiftCompilerSources/Sources/Optimizer/Analysis/CalleeAnalysis.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@ public struct CalleeAnalysis {
1919
public func getCallees(callee: Value) -> FunctionArray {
2020
return FunctionArray(bridged: CalleeAnalysis_getCallees(bridged, callee.bridged))
2121
}
22+
23+
public func getDestructors(destroyInst: Instruction) -> FunctionArray {
24+
return FunctionArray(bridged:
25+
CalleeAnalysis_getInstCallees(bridged, destroyInst.bridged))
26+
}
2227
}
2328

24-
public struct FunctionArray : RandomAccessCollection, CustomReflectable {
29+
public struct FunctionArray : RandomAccessCollection, FormattedLikeArray {
2530
fileprivate let bridged: BridgedCalleeList
2631

2732
public var startIndex: Int { 0 }
@@ -32,9 +37,4 @@ public struct FunctionArray : RandomAccessCollection, CustomReflectable {
3237
}
3338

3439
public var allCalleesKnown: Bool { bridged.incomplete == 0 }
35-
36-
public var customMirror: Mirror {
37-
let c: [Mirror.Child] = map { (label: nil, value: $0.name) }
38-
return Mirror(self, children: c)
39-
}
4040
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===--- DeadEndBlocksAnalysis.swift - the dead-end blocks analysis -------===//
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 OptimizerBridging
14+
import SIL
15+
16+
public struct DeadEndBlocksAnalysis {
17+
let bridged: BridgedDeadEndBlocksAnalysis
18+
19+
public func isDeadEnd(_ block: BasicBlock) -> Bool {
20+
return DeadEndBlocksAnalysis_isDeadEnd(bridged, block.bridged) != 0
21+
}
22+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===--- DominatorTree.swift - the dominator tree -------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 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+
import OptimizerBridging
15+
16+
public struct DominatorTree {
17+
let bridged: BridgedDomTree
18+
}
19+
20+
extension BasicBlock {
21+
func dominates(_ other: BasicBlock, _ domTree: DominatorTree) -> Bool {
22+
DominatorTree_dominates(domTree.bridged, self.bridged, other.bridged) != 0
23+
}
24+
25+
func strictlyDominates(_ other: BasicBlock, _ domTree: DominatorTree) -> Bool {
26+
dominates(other, domTree) && self != other
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===--- PostDominatorTree.swift - the post dominator tree ----------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 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+
import OptimizerBridging
15+
16+
public struct PostDominatorTree {
17+
let bridged: BridgedPostDomTree
18+
}
19+
20+
extension BasicBlock {
21+
func postDominates(_ other: BasicBlock, _ pdomTree: PostDominatorTree) -> Bool {
22+
PostDominatorTree_postDominates(pdomTree.bridged, self.bridged, other.bridged) != 0
23+
}
24+
25+
func strictlyPostDominates(_ other: BasicBlock, _ pdomTree: PostDominatorTree) -> Bool {
26+
postDominates(other, pdomTree) && self != other
27+
}
28+
}

SwiftCompilerSources/Sources/Optimizer/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ endif()
1515
add_swift_compiler_module(Optimizer DEPENDS ${dependencies})
1616

1717
add_subdirectory(Analysis)
18+
add_subdirectory(DataStructures)
1819
add_subdirectory(InstructionPasses)
1920
add_subdirectory(PassManager)
2021
add_subdirectory(FunctionPasses)
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
//===--- BasicBlockRange.swift - a range of basic blocks ------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 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+
/// A range of basic blocks.
16+
///
17+
/// The `BasicBlockRange` defines a range from a dominating "begin" block to one or more "end" blocks.
18+
/// The range is "exclusive", which means that the "end" blocks are not part of the range.
19+
///
20+
/// The `BasicBlockRange` is in the same spirit as a linear range, but as the control flow is a graph
21+
/// and not a linear list, there can be "exit" blocks from within the range.
22+
///
23+
/// One or more "potential" end blocks can be inserted.
24+
/// Though, not all inserted blocks end up as "end" blocks.
25+
///
26+
/// There are several kind of blocks:
27+
/// * begin: it is a single block which dominates all blocks of the range
28+
/// * range: all blocks from which there is a path from the begin block to any of the end blocks
29+
/// * ends: all inserted blocks which are at the end of the range
30+
/// * exits: all successor blocks of range blocks which are not in the range themselves
31+
/// * interiors: all inserted blocks which are not end blocks.
32+
///
33+
/// In the following example, let's assume `B` is the begin block and `I1`, `I2` and `I3`
34+
/// were inserted as potential end blocks:
35+
///
36+
/// B
37+
/// / \
38+
/// I1 I2
39+
/// / \
40+
/// I3 X
41+
///
42+
/// Then `I1` and `I3` are "end" blocks. `I2` is an interior block and `X` is an exit block.
43+
/// The range consists of `B` and `I2`. Note that the range does not include `I1` and `I3`
44+
/// because it's an _exclusive_ range.
45+
///
46+
/// This type should be a move-only type, but unfortunately we don't have move-only
47+
/// types yet. Therefore it's needed to call `deinitialize()` explicitly to
48+
/// destruct this data structure, e.g. in a `defer {}` block.
49+
struct BasicBlockRange : CustomStringConvertible, CustomReflectable {
50+
51+
/// The dominating begin block.
52+
let begin: BasicBlock
53+
54+
/// The exclusive range, i.e. not containing the end blocks.
55+
private(set) var range: Stack<BasicBlock>
56+
57+
/// All inserted blocks.
58+
private(set) var inserted: Stack<BasicBlock>
59+
60+
private var insertedSet: BasicBlockSet
61+
private var worklist: BasicBlockWorklist
62+
63+
init(begin: BasicBlock, _ context: PassContext) {
64+
self.begin = begin
65+
self.range = Stack(context)
66+
self.inserted = Stack(context)
67+
self.insertedSet = BasicBlockSet(context)
68+
self.worklist = BasicBlockWorklist(context)
69+
}
70+
71+
/// Insert a potential end block.
72+
mutating func insert(_ block: BasicBlock) {
73+
if !insertedSet.contains(block) {
74+
insertedSet.insert(block)
75+
inserted.append(block)
76+
}
77+
if block != begin {
78+
worklist.pushIfNotVisited(contentsOf: block.predecessors)
79+
80+
while let b = worklist.pop() {
81+
range.append(b)
82+
if b != begin {
83+
worklist.pushIfNotVisited(contentsOf: b.predecessors)
84+
}
85+
}
86+
}
87+
}
88+
89+
/// Returns true if the exclusive range contains `block`.
90+
func contains(_ block: BasicBlock) -> Bool { worklist.hasBeenPushed(block) }
91+
92+
/// Returns true if the inclusive range contains `block`.
93+
func inclusiveRangeContains (_ block: BasicBlock) -> Bool {
94+
contains(block) || insertedSet.contains(block)
95+
}
96+
97+
/// Returns true if the range is valid and that's iff the begin block dominates all blocks of the range.
98+
var isValid: Bool {
99+
let entry = begin.function.entryBlock
100+
return begin == entry ||
101+
// If any block in the range is not dominated by `begin`, the range propagates back to the entry block.
102+
!inclusiveRangeContains(entry)
103+
}
104+
105+
/// Returns the end blocks.
106+
var ends: LazyFilterSequence<Stack<BasicBlock>> {
107+
inserted.lazy.filter { !worklist.hasBeenPushed($0) }
108+
}
109+
110+
/// Returns the exit blocks.
111+
var exits: LazySequence<FlattenSequence<
112+
LazyMapSequence<Stack<BasicBlock>,
113+
LazyFilterSequence<SuccessorArray>>>> {
114+
range.lazy.flatMap {
115+
$0.successors.lazy.filter {
116+
!inclusiveRangeContains($0) || $0 == begin
117+
}
118+
}
119+
}
120+
121+
/// Returns the interior blocks.
122+
var interiors: LazyFilterSequence<Stack<BasicBlock>> {
123+
inserted.lazy.filter { contains($0) && $0 != begin }
124+
}
125+
126+
var description: String {
127+
"""
128+
begin: \(begin.name)
129+
range: \(range)
130+
ends: \(ends)
131+
exits: \(exits)
132+
interiors: \(interiors)
133+
"""
134+
}
135+
136+
var customMirror: Mirror { Mirror(self, children: []) }
137+
138+
/// TODO: once we have move-only types, make this a real deinit.
139+
mutating func deinitialize() {
140+
worklist.deinitialize()
141+
inserted.deinitialize()
142+
insertedSet.deinitialize()
143+
range.deinitialize()
144+
}
145+
}

0 commit comments

Comments
 (0)