mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Swift Bridging: use C++ instead of C bridging for the optimizer
This commit is contained in:
@@ -17,7 +17,7 @@ struct AliasAnalysis {
|
|||||||
let bridged: BridgedAliasAnalysis
|
let bridged: BridgedAliasAnalysis
|
||||||
|
|
||||||
func mayRead(_ inst: Instruction, fromAddress: Value) -> Bool {
|
func mayRead(_ inst: Instruction, fromAddress: Value) -> Bool {
|
||||||
switch AliasAnalysis_getMemBehavior(bridged, inst.bridged, fromAddress.bridged) {
|
switch bridged.getMemBehavior(inst.bridged, fromAddress.bridged) {
|
||||||
case .MayRead, .MayReadWrite, .MayHaveSideEffects:
|
case .MayRead, .MayReadWrite, .MayHaveSideEffects:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
@@ -26,7 +26,7 @@ struct AliasAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mayWrite(_ inst: Instruction, toAddress: Value) -> Bool {
|
func mayWrite(_ inst: Instruction, toAddress: Value) -> Bool {
|
||||||
switch AliasAnalysis_getMemBehavior(bridged, inst.bridged, toAddress.bridged) {
|
switch bridged.getMemBehavior(inst.bridged, toAddress.bridged) {
|
||||||
case .MayWrite, .MayReadWrite, .MayHaveSideEffects:
|
case .MayWrite, .MayReadWrite, .MayHaveSideEffects:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
@@ -35,7 +35,7 @@ struct AliasAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mayReadOrWrite(_ inst: Instruction, address: Value) -> Bool {
|
func mayReadOrWrite(_ inst: Instruction, address: Value) -> Bool {
|
||||||
switch AliasAnalysis_getMemBehavior(bridged, inst.bridged, address.bridged) {
|
switch bridged.getMemBehavior(inst.bridged, address.bridged) {
|
||||||
case .MayRead, .MayWrite, .MayReadWrite, .MayHaveSideEffects:
|
case .MayRead, .MayWrite, .MayReadWrite, .MayHaveSideEffects:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
@@ -61,7 +61,7 @@ struct AliasAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func register() {
|
static func register() {
|
||||||
AliasAnalysis_register(
|
BridgedAliasAnalysis.registerAnalysis(
|
||||||
// getMemEffectsFn
|
// getMemEffectsFn
|
||||||
{ (bridgedCtxt: BridgedPassContext, bridgedVal: BridgedValue, bridgedInst: BridgedInstruction) -> swift.MemoryBehavior in
|
{ (bridgedCtxt: BridgedPassContext, bridgedVal: BridgedValue, bridgedInst: BridgedInstruction) -> swift.MemoryBehavior in
|
||||||
let context = FunctionPassContext(_bridged: bridgedCtxt)
|
let context = FunctionPassContext(_bridged: bridgedCtxt)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public struct CalleeAnalysis {
|
|||||||
let bridged: BridgedCalleeAnalysis
|
let bridged: BridgedCalleeAnalysis
|
||||||
|
|
||||||
static func register() {
|
static func register() {
|
||||||
CalleeAnalysis_register(
|
BridgedCalleeAnalysis.registerAnalysis(
|
||||||
// isDeinitBarrierFn:
|
// isDeinitBarrierFn:
|
||||||
{ (inst : BridgedInstruction, bca: BridgedCalleeAnalysis) -> Bool in
|
{ (inst : BridgedInstruction, bca: BridgedCalleeAnalysis) -> Bool in
|
||||||
return inst.instruction.isDeinitBarrier(bca.analysis)
|
return inst.instruction.isDeinitBarrier(bca.analysis)
|
||||||
@@ -33,19 +33,19 @@ public struct CalleeAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func getCallees(callee: Value) -> FunctionArray? {
|
public func getCallees(callee: Value) -> FunctionArray? {
|
||||||
let bridgedFuncs = CalleeAnalysis_getCallees(bridged, callee.bridged)
|
let bridgedFuncs = bridged.getCallees(callee.bridged)
|
||||||
if bridgedFuncs.incomplete != 0 {
|
if bridgedFuncs.isIncomplete() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return FunctionArray(bridged: bridgedFuncs)
|
return FunctionArray(bridged: bridgedFuncs)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getIncompleteCallees(callee: Value) -> FunctionArray {
|
public func getIncompleteCallees(callee: Value) -> FunctionArray {
|
||||||
return FunctionArray(bridged: CalleeAnalysis_getCallees(bridged, callee.bridged))
|
return FunctionArray(bridged: bridged.getCallees(callee.bridged))
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getDestructor(ofExactType type: Type) -> Function? {
|
public func getDestructor(ofExactType type: Type) -> Function? {
|
||||||
let destructors = FunctionArray(bridged: CalleeAnalysis_getDestructors(bridged, type.bridged, /*isExactType*/ 1))
|
let destructors = FunctionArray(bridged: bridged.getDestructors(type.bridged, /*isExactType*/ true))
|
||||||
if destructors.count == 1 {
|
if destructors.count == 1 {
|
||||||
return destructors[0]
|
return destructors[0]
|
||||||
}
|
}
|
||||||
@@ -53,8 +53,8 @@ public struct CalleeAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func getDestructors(of type: Type) -> FunctionArray? {
|
public func getDestructors(of type: Type) -> FunctionArray? {
|
||||||
let bridgedDtors = CalleeAnalysis_getDestructors(bridged, type.bridged, /*isExactType*/ 0)
|
let bridgedDtors = bridged.getDestructors(type.bridged, /*isExactType*/ false)
|
||||||
if bridgedDtors.incomplete != 0 {
|
if bridgedDtors.isIncomplete() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return FunctionArray(bridged: bridgedDtors)
|
return FunctionArray(bridged: bridgedDtors)
|
||||||
@@ -123,13 +123,13 @@ extension Instruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct FunctionArray : RandomAccessCollection, FormattedLikeArray {
|
public struct FunctionArray : RandomAccessCollection, FormattedLikeArray {
|
||||||
fileprivate let bridged: BridgedCalleeList
|
fileprivate let bridged: swift.CalleeList
|
||||||
|
|
||||||
public var startIndex: Int { 0 }
|
public var startIndex: Int { 0 }
|
||||||
public var endIndex: Int { BridgedFunctionArray_size(bridged) }
|
public var endIndex: Int { Int(bridged.getCount()) }
|
||||||
|
|
||||||
public subscript(_ index: Int) -> Function {
|
public subscript(_ index: Int) -> Function {
|
||||||
return BridgedFunctionArray_get(bridged, index).function
|
return BridgedCalleeAnalysis.getCallee(bridged, index).function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Bridging utilities
|
// Bridging utilities
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ public struct DeadEndBlocksAnalysis {
|
|||||||
let bridged: BridgedDeadEndBlocksAnalysis
|
let bridged: BridgedDeadEndBlocksAnalysis
|
||||||
|
|
||||||
public func isDeadEnd(_ block: BasicBlock) -> Bool {
|
public func isDeadEnd(_ block: BasicBlock) -> Bool {
|
||||||
return DeadEndBlocksAnalysis_isDeadEnd(bridged, block.bridged) != 0
|
return bridged.isDeadEnd(block.bridged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public struct DominatorTree {
|
|||||||
|
|
||||||
extension BasicBlock {
|
extension BasicBlock {
|
||||||
func dominates(_ other: BasicBlock, _ domTree: DominatorTree) -> Bool {
|
func dominates(_ other: BasicBlock, _ domTree: DominatorTree) -> Bool {
|
||||||
DominatorTree_dominates(domTree.bridged, self.bridged, other.bridged) != 0
|
domTree.bridged.dominates(self.bridged, other.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
func strictlyDominates(_ other: BasicBlock, _ domTree: DominatorTree) -> Bool {
|
func strictlyDominates(_ other: BasicBlock, _ domTree: DominatorTree) -> Bool {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public struct PostDominatorTree {
|
|||||||
|
|
||||||
extension BasicBlock {
|
extension BasicBlock {
|
||||||
func postDominates(_ other: BasicBlock, _ pdomTree: PostDominatorTree) -> Bool {
|
func postDominates(_ other: BasicBlock, _ pdomTree: PostDominatorTree) -> Bool {
|
||||||
PostDominatorTree_postDominates(pdomTree.bridged, self.bridged, other.bridged) != 0
|
pdomTree.bridged.postDominates(self.bridged, other.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
func strictlyPostDominates(_ other: BasicBlock, _ pdomTree: PostDominatorTree) -> Bool {
|
func strictlyPostDominates(_ other: BasicBlock, _ pdomTree: PostDominatorTree) -> Bool {
|
||||||
|
|||||||
@@ -38,25 +38,25 @@ struct BasicBlockSet : IntrusiveSet {
|
|||||||
|
|
||||||
init(_ context: some Context) {
|
init(_ context: some Context) {
|
||||||
self.context = context._bridged
|
self.context = context._bridged
|
||||||
self.bridged = PassContext_allocBasicBlockSet(self.context)
|
self.bridged = self.context.allocBasicBlockSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
func contains(_ block: BasicBlock) -> Bool {
|
func contains(_ block: BasicBlock) -> Bool {
|
||||||
BasicBlockSet_contains(bridged, block.bridged) != 0
|
bridged.contains(block.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if `block` was not contained in the set before inserting.
|
/// Returns true if `block` was not contained in the set before inserting.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
mutating func insert(_ block: BasicBlock) -> Bool {
|
mutating func insert(_ block: BasicBlock) -> Bool {
|
||||||
BasicBlockSet_insert(bridged, block.bridged) != 0
|
bridged.insert(block.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func erase(_ block: BasicBlock) {
|
mutating func erase(_ block: BasicBlock) {
|
||||||
BasicBlockSet_erase(bridged, block.bridged)
|
bridged.erase(block.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
var description: String {
|
var description: String {
|
||||||
let function = BasicBlockSet_getFunction(bridged).function
|
let function = bridged.getFunction().function
|
||||||
let blockNames = function.blocks.enumerated().filter { contains($0.1) }
|
let blockNames = function.blocks.enumerated().filter { contains($0.1) }
|
||||||
.map { "bb\($0.0)"}
|
.map { "bb\($0.0)"}
|
||||||
return "{" + blockNames.joined(separator: ", ") + "}"
|
return "{" + blockNames.joined(separator: ", ") + "}"
|
||||||
@@ -64,7 +64,7 @@ struct BasicBlockSet : IntrusiveSet {
|
|||||||
|
|
||||||
/// TODO: once we have move-only types, make this a real deinit.
|
/// TODO: once we have move-only types, make this a real deinit.
|
||||||
mutating func deinitialize() {
|
mutating func deinitialize() {
|
||||||
PassContext_freeBasicBlockSet(context, bridged)
|
context.freeBasicBlockSet(bridged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,25 +83,25 @@ struct ValueSet : IntrusiveSet {
|
|||||||
|
|
||||||
init(_ context: some Context) {
|
init(_ context: some Context) {
|
||||||
self.context = context._bridged
|
self.context = context._bridged
|
||||||
self.bridged = PassContext_allocNodeSet(self.context)
|
self.bridged = self.context.allocNodeSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
func contains(_ value: Value) -> Bool {
|
func contains(_ value: Value) -> Bool {
|
||||||
NodeSet_containsValue(bridged, value.bridged) != 0
|
bridged.containsValue(value.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if `value` was not contained in the set before inserting.
|
/// Returns true if `value` was not contained in the set before inserting.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
mutating func insert(_ value: Value) -> Bool {
|
mutating func insert(_ value: Value) -> Bool {
|
||||||
NodeSet_insertValue(bridged, value.bridged) != 0
|
bridged.insertValue(value.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func erase(_ value: Value) {
|
mutating func erase(_ value: Value) {
|
||||||
NodeSet_eraseValue(bridged, value.bridged)
|
bridged.eraseValue(value.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
var description: String {
|
var description: String {
|
||||||
let function = NodeSet_getFunction(bridged).function
|
let function = bridged.getFunction().function
|
||||||
var d = "{\n"
|
var d = "{\n"
|
||||||
for block in function.blocks {
|
for block in function.blocks {
|
||||||
for arg in block.arguments {
|
for arg in block.arguments {
|
||||||
@@ -123,7 +123,7 @@ struct ValueSet : IntrusiveSet {
|
|||||||
|
|
||||||
/// TODO: once we have move-only types, make this a real deinit.
|
/// TODO: once we have move-only types, make this a real deinit.
|
||||||
mutating func deinitialize() {
|
mutating func deinitialize() {
|
||||||
PassContext_freeNodeSet(context, bridged)
|
context.freeNodeSet(bridged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,25 +142,25 @@ struct InstructionSet : IntrusiveSet {
|
|||||||
|
|
||||||
init(_ context: some Context) {
|
init(_ context: some Context) {
|
||||||
self.context = context._bridged
|
self.context = context._bridged
|
||||||
self.bridged = PassContext_allocNodeSet(self.context)
|
self.bridged = self.context.allocNodeSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
func contains(_ inst: Instruction) -> Bool {
|
func contains(_ inst: Instruction) -> Bool {
|
||||||
NodeSet_containsInstruction(bridged, inst.bridged) != 0
|
bridged.containsInstruction(inst.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if `inst` was not contained in the set before inserting.
|
/// Returns true if `inst` was not contained in the set before inserting.
|
||||||
@discardableResult
|
@discardableResult
|
||||||
mutating func insert(_ inst: Instruction) -> Bool {
|
mutating func insert(_ inst: Instruction) -> Bool {
|
||||||
NodeSet_insertInstruction(bridged, inst.bridged) != 0
|
bridged.insertInstruction(inst.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func erase(_ inst: Instruction) {
|
mutating func erase(_ inst: Instruction) {
|
||||||
NodeSet_eraseInstruction(bridged, inst.bridged)
|
bridged.eraseInstruction(inst.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
var description: String {
|
var description: String {
|
||||||
let function = NodeSet_getFunction(bridged).function
|
let function = bridged.getFunction().function
|
||||||
var d = "{\n"
|
var d = "{\n"
|
||||||
for inst in function.instructions {
|
for inst in function.instructions {
|
||||||
if contains(inst) {
|
if contains(inst) {
|
||||||
@@ -173,6 +173,6 @@ struct InstructionSet : IntrusiveSet {
|
|||||||
|
|
||||||
/// TODO: once we have move-only types, make this a real deinit.
|
/// TODO: once we have move-only types, make this a real deinit.
|
||||||
mutating func deinitialize() {
|
mutating func deinitialize() {
|
||||||
PassContext_freeNodeSet(context, bridged)
|
context.freeNodeSet(bridged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,22 +27,22 @@ import SIL
|
|||||||
struct Stack<Element> : CollectionLikeSequence {
|
struct Stack<Element> : CollectionLikeSequence {
|
||||||
|
|
||||||
private let bridgedContext: BridgedPassContext
|
private let bridgedContext: BridgedPassContext
|
||||||
private var firstSlab = BridgedSlab(data: nil)
|
private var firstSlab = BridgedPassContext.Slab(nil)
|
||||||
private var lastSlab = BridgedSlab(data: nil)
|
private var lastSlab = BridgedPassContext.Slab(nil)
|
||||||
private var endIndex: Int = 0
|
private var endIndex: Int = 0
|
||||||
|
|
||||||
private static var slabCapacity: Int {
|
private static var slabCapacity: Int {
|
||||||
BridgedSlabCapacity / MemoryLayout<Element>.stride
|
BridgedPassContext.Slab.getCapacity() / MemoryLayout<Element>.stride
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func bind(_ slab: BridgedSlab) -> UnsafeMutablePointer<Element> {
|
private static func bind(_ slab: BridgedPassContext.Slab) -> UnsafeMutablePointer<Element> {
|
||||||
return slab.data!.bindMemory(to: Element.self, capacity: Stack.slabCapacity)
|
return UnsafeMutableRawPointer(slab.data!).bindMemory(to: Element.self, capacity: Stack.slabCapacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Iterator : IteratorProtocol {
|
struct Iterator : IteratorProtocol {
|
||||||
var slab: BridgedSlab
|
var slab: BridgedPassContext.Slab
|
||||||
var index: Int
|
var index: Int
|
||||||
let lastSlab: BridgedSlab
|
let lastSlab: BridgedPassContext.Slab
|
||||||
let endIndex: Int
|
let endIndex: Int
|
||||||
|
|
||||||
mutating func next() -> Element? {
|
mutating func next() -> Element? {
|
||||||
@@ -52,7 +52,7 @@ struct Stack<Element> : CollectionLikeSequence {
|
|||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
if index >= end && slab.data != lastSlab.data {
|
if index >= end && slab.data != lastSlab.data {
|
||||||
slab = PassContext_getNextSlab(slab)
|
slab = slab.getNext()
|
||||||
index = 0
|
index = 0
|
||||||
}
|
}
|
||||||
return elem
|
return elem
|
||||||
@@ -77,11 +77,11 @@ struct Stack<Element> : CollectionLikeSequence {
|
|||||||
|
|
||||||
mutating func push(_ element: Element) {
|
mutating func push(_ element: Element) {
|
||||||
if endIndex >= Stack.slabCapacity {
|
if endIndex >= Stack.slabCapacity {
|
||||||
lastSlab = PassContext_allocSlab(bridgedContext, lastSlab)
|
lastSlab = bridgedContext.allocSlab(lastSlab)
|
||||||
endIndex = 0
|
endIndex = 0
|
||||||
} else if firstSlab.data == nil {
|
} else if firstSlab.data == nil {
|
||||||
assert(endIndex == 0)
|
assert(endIndex == 0)
|
||||||
firstSlab = PassContext_allocSlab(bridgedContext, lastSlab)
|
firstSlab = bridgedContext.allocSlab(lastSlab)
|
||||||
lastSlab = firstSlab
|
lastSlab = firstSlab
|
||||||
}
|
}
|
||||||
(Stack.bind(lastSlab) + endIndex).initialize(to: element)
|
(Stack.bind(lastSlab) + endIndex).initialize(to: element)
|
||||||
@@ -109,12 +109,12 @@ struct Stack<Element> : CollectionLikeSequence {
|
|||||||
|
|
||||||
if endIndex == 0 {
|
if endIndex == 0 {
|
||||||
if lastSlab.data == firstSlab.data {
|
if lastSlab.data == firstSlab.data {
|
||||||
_ = PassContext_freeSlab(bridgedContext, lastSlab)
|
_ = bridgedContext.freeSlab(lastSlab)
|
||||||
firstSlab.data = nil
|
firstSlab.data = nil
|
||||||
lastSlab.data = nil
|
lastSlab.data = nil
|
||||||
endIndex = 0
|
endIndex = 0
|
||||||
} else {
|
} else {
|
||||||
lastSlab = PassContext_freeSlab(bridgedContext, lastSlab)
|
lastSlab = bridgedContext.freeSlab(lastSlab)
|
||||||
endIndex = Stack.slabCapacity
|
endIndex = Stack.slabCapacity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ extension Context {
|
|||||||
// The calleeAnalysis is not specific to a function and therefore can be provided in
|
// The calleeAnalysis is not specific to a function and therefore can be provided in
|
||||||
// all contexts.
|
// all contexts.
|
||||||
var calleeAnalysis: CalleeAnalysis {
|
var calleeAnalysis: CalleeAnalysis {
|
||||||
let bridgeCA = PassContext_getCalleeAnalysis(_bridged)
|
let bridgeCA = _bridged.getCalleeAnalysis()
|
||||||
return CalleeAnalysis(bridged: bridgeCA)
|
return CalleeAnalysis(bridged: bridgeCA)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,8 +36,8 @@ protocol MutatingContext : Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension MutatingContext {
|
extension MutatingContext {
|
||||||
func notifyInvalidatedStackNesting() { PassContext_notifyInvalidatedStackNesting(_bridged) }
|
func notifyInvalidatedStackNesting() { _bridged.notifyInvalidatedStackNesting() }
|
||||||
var needFixStackNesting: Bool { PassContext_getNeedFixStackNesting(_bridged) }
|
var needFixStackNesting: Bool { _bridged.getNeedFixStackNesting() }
|
||||||
|
|
||||||
/// Splits the basic block, which contains `inst`, before `inst` and returns the
|
/// Splits the basic block, which contains `inst`, before `inst` and returns the
|
||||||
/// new block.
|
/// new block.
|
||||||
@@ -46,7 +46,7 @@ extension MutatingContext {
|
|||||||
/// instructions _before_ `inst` remain in the original block.
|
/// instructions _before_ `inst` remain in the original block.
|
||||||
func splitBlock(at inst: Instruction) -> BasicBlock {
|
func splitBlock(at inst: Instruction) -> BasicBlock {
|
||||||
notifyBranchesChanged()
|
notifyBranchesChanged()
|
||||||
return PassContext_splitBlock(inst.bridged).block
|
return _bridged.splitBlock(inst.bridged).block
|
||||||
}
|
}
|
||||||
|
|
||||||
func erase(instruction: Instruction) {
|
func erase(instruction: Instruction) {
|
||||||
@@ -58,7 +58,7 @@ extension MutatingContext {
|
|||||||
}
|
}
|
||||||
notifyInstructionsChanged()
|
notifyInstructionsChanged()
|
||||||
|
|
||||||
PassContext_eraseInstruction(_bridged, instruction.bridged)
|
_bridged.eraseInstruction(instruction.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
func erase(instructionIncludingDebugUses inst: Instruction) {
|
func erase(instructionIncludingDebugUses inst: Instruction) {
|
||||||
@@ -72,25 +72,25 @@ extension MutatingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tryDeleteDeadClosure(closure: SingleValueInstruction) -> Bool {
|
func tryDeleteDeadClosure(closure: SingleValueInstruction) -> Bool {
|
||||||
PassContext_tryDeleteDeadClosure(_bridged, closure.bridged)
|
_bridged.tryDeleteDeadClosure(closure.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContextSubstitutionMap(for type: Type) -> SubstitutionMap {
|
func getContextSubstitutionMap(for type: Type) -> SubstitutionMap {
|
||||||
SubstitutionMap(PassContext_getContextSubstitutionMap(_bridged, type.bridged))
|
SubstitutionMap(_bridged.getContextSubstitutionMap(type.bridged))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private utilities
|
// Private utilities
|
||||||
|
|
||||||
fileprivate func notifyInstructionsChanged() {
|
fileprivate func notifyInstructionsChanged() {
|
||||||
PassContext_notifyChanges(_bridged, instructionsChanged)
|
_bridged.asNotificationHandler().notifyChanges(.instructionsChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func notifyCallsChanged() {
|
fileprivate func notifyCallsChanged() {
|
||||||
PassContext_notifyChanges(_bridged, callsChanged)
|
_bridged.asNotificationHandler().notifyChanges(.callsChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func notifyBranchesChanged() {
|
fileprivate func notifyBranchesChanged() {
|
||||||
PassContext_notifyChanges(_bridged, branchesChanged)
|
_bridged.asNotificationHandler().notifyChanges(.branchesChanged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ struct FunctionPassContext : MutatingContext {
|
|||||||
|
|
||||||
func continueWithNextSubpassRun(for inst: Instruction? = nil) -> Bool {
|
func continueWithNextSubpassRun(for inst: Instruction? = nil) -> Bool {
|
||||||
let bridgedInst = OptionalBridgedInstruction(inst?.bridged.obj)
|
let bridgedInst = OptionalBridgedInstruction(inst?.bridged.obj)
|
||||||
return PassContext_continueWithNextSubpassRun(_bridged, bridgedInst) != 0
|
return _bridged.continueWithNextSubpassRun(bridgedInst)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSimplifyContext(preserveDebugInfo: Bool, notifyInstructionChanged: @escaping (Instruction) -> ()) -> SimplifyContext {
|
func createSimplifyContext(preserveDebugInfo: Bool, notifyInstructionChanged: @escaping (Instruction) -> ()) -> SimplifyContext {
|
||||||
@@ -111,33 +111,33 @@ struct FunctionPassContext : MutatingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var aliasAnalysis: AliasAnalysis {
|
var aliasAnalysis: AliasAnalysis {
|
||||||
let bridgedAA = PassContext_getAliasAnalysis(_bridged)
|
let bridgedAA = _bridged.getAliasAnalysis()
|
||||||
return AliasAnalysis(bridged: bridgedAA)
|
return AliasAnalysis(bridged: bridgedAA)
|
||||||
}
|
}
|
||||||
|
|
||||||
var deadEndBlocks: DeadEndBlocksAnalysis {
|
var deadEndBlocks: DeadEndBlocksAnalysis {
|
||||||
let bridgeDEA = PassContext_getDeadEndBlocksAnalysis(_bridged)
|
let bridgeDEA = _bridged.getDeadEndBlocksAnalysis()
|
||||||
return DeadEndBlocksAnalysis(bridged: bridgeDEA)
|
return DeadEndBlocksAnalysis(bridged: bridgeDEA)
|
||||||
}
|
}
|
||||||
|
|
||||||
var dominatorTree: DominatorTree {
|
var dominatorTree: DominatorTree {
|
||||||
let bridgedDT = PassContext_getDomTree(_bridged)
|
let bridgedDT = _bridged.getDomTree()
|
||||||
return DominatorTree(bridged: bridgedDT)
|
return DominatorTree(bridged: bridgedDT)
|
||||||
}
|
}
|
||||||
|
|
||||||
var postDominatorTree: PostDominatorTree {
|
var postDominatorTree: PostDominatorTree {
|
||||||
let bridgedPDT = PassContext_getPostDomTree(_bridged)
|
let bridgedPDT = _bridged.getPostDomTree()
|
||||||
return PostDominatorTree(bridged: bridgedPDT)
|
return PostDominatorTree(bridged: bridgedPDT)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadFunction(name: StaticString) -> Function? {
|
func loadFunction(name: StaticString) -> Function? {
|
||||||
return name.withUTF8Buffer { (nameBuffer: UnsafeBufferPointer<UInt8>) in
|
return name.withUTF8Buffer { (nameBuffer: UnsafeBufferPointer<UInt8>) in
|
||||||
PassContext_loadFunction(_bridged, llvm.StringRef(nameBuffer.baseAddress, nameBuffer.count)).function
|
_bridged.loadFunction(llvm.StringRef(nameBuffer.baseAddress, nameBuffer.count)).function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func erase(block: BasicBlock) {
|
func erase(block: BasicBlock) {
|
||||||
PassContext_eraseBlock(_bridged, block.bridged)
|
_bridged.eraseBlock(block.bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
func modifyEffects(in function: Function, _ body: (inout FunctionEffects) -> ()) {
|
func modifyEffects(in function: Function, _ body: (inout FunctionEffects) -> ()) {
|
||||||
@@ -146,7 +146,7 @@ struct FunctionPassContext : MutatingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func notifyEffectsChanged() {
|
fileprivate func notifyEffectsChanged() {
|
||||||
PassContext_notifyChanges(_bridged, effectsChanged)
|
_bridged.asNotificationHandler().notifyChanges(.effectsChanged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,23 +164,23 @@ extension Builder {
|
|||||||
/// Creates a builder which inserts _before_ `insPnt`, using a custom `location`.
|
/// Creates a builder which inserts _before_ `insPnt`, using a custom `location`.
|
||||||
init(before insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
init(before insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
||||||
self.init(insertAt: .before(insPnt), location: location,
|
self.init(insertAt: .before(insPnt), location: location,
|
||||||
context.notifyInstructionChanged, context._bridged)
|
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a builder which inserts _before_ `insPnt`, using the location of `insPnt`.
|
/// Creates a builder which inserts _before_ `insPnt`, using the location of `insPnt`.
|
||||||
init(before insPnt: Instruction, _ context: some MutatingContext) {
|
init(before insPnt: Instruction, _ context: some MutatingContext) {
|
||||||
self.init(insertAt: .before(insPnt), location: insPnt.location,
|
self.init(insertAt: .before(insPnt), location: insPnt.location,
|
||||||
context.notifyInstructionChanged, context._bridged)
|
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a builder which inserts _after_ `insPnt`, using a custom `location`.
|
/// Creates a builder which inserts _after_ `insPnt`, using a custom `location`.
|
||||||
init(after insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
init(after insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
||||||
if let nextInst = insPnt.next {
|
if let nextInst = insPnt.next {
|
||||||
self.init(insertAt: .before(nextInst), location: location,
|
self.init(insertAt: .before(nextInst), location: location,
|
||||||
context.notifyInstructionChanged, context._bridged)
|
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
|
||||||
} else {
|
} else {
|
||||||
self.init(insertAt: .atEndOf(insPnt.parentBlock), location: location,
|
self.init(insertAt: .atEndOf(insPnt.parentBlock), location: location,
|
||||||
context.notifyInstructionChanged, context._bridged)
|
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,14 +192,14 @@ extension Builder {
|
|||||||
/// Creates a builder which inserts at the end of `block`, using a custom `location`.
|
/// Creates a builder which inserts at the end of `block`, using a custom `location`.
|
||||||
init(atEndOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
init(atEndOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
||||||
self.init(insertAt: .atEndOf(block), location: location,
|
self.init(insertAt: .atEndOf(block), location: location,
|
||||||
context.notifyInstructionChanged, context._bridged)
|
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a builder which inserts at the begin of `block`, using a custom `location`.
|
/// Creates a builder which inserts at the begin of `block`, using a custom `location`.
|
||||||
init(atBeginOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
init(atBeginOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
||||||
let firstInst = block.instructions.first!
|
let firstInst = block.instructions.first!
|
||||||
self.init(insertAt: .before(firstInst), location: location,
|
self.init(insertAt: .before(firstInst), location: location,
|
||||||
context.notifyInstructionChanged, context._bridged)
|
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a builder which inserts at the begin of `block`, using the location of the first
|
/// Creates a builder which inserts at the begin of `block`, using the location of the first
|
||||||
@@ -207,7 +207,7 @@ extension Builder {
|
|||||||
init(atBeginOf block: BasicBlock, _ context: some MutatingContext) {
|
init(atBeginOf block: BasicBlock, _ context: some MutatingContext) {
|
||||||
let firstInst = block.instructions.first!
|
let firstInst = block.instructions.first!
|
||||||
self.init(insertAt: .before(firstInst), location: firstInst.location,
|
self.init(insertAt: .before(firstInst), location: firstInst.location,
|
||||||
context.notifyInstructionChanged, context._bridged)
|
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ extension Builder {
|
|||||||
|
|
||||||
extension Undef {
|
extension Undef {
|
||||||
static func get(type: Type, _ context: some MutatingContext) -> Undef {
|
static func get(type: Type, _ context: some MutatingContext) -> Undef {
|
||||||
SILUndef_get(type.bridged, context._bridged).value as! Undef
|
context._bridged.getSILUndef(type.bridged).value as! Undef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ extension BasicBlock {
|
|||||||
extension AllocRefInstBase {
|
extension AllocRefInstBase {
|
||||||
func setIsStackAllocatable(_ context: some MutatingContext) {
|
func setIsStackAllocatable(_ context: some MutatingContext) {
|
||||||
context.notifyInstructionsChanged()
|
context.notifyInstructionsChanged()
|
||||||
AllocRefInstBase_setIsStackAllocatable(bridged)
|
bridged.AllocRefInstBase_setIsStackAllocatable()
|
||||||
context.notifyInstructionChanged(self)
|
context.notifyInstructionChanged(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,7 +294,7 @@ extension RefCountingInst {
|
|||||||
extension TermInst {
|
extension TermInst {
|
||||||
func replaceBranchTarget(from fromBlock: BasicBlock, to toBlock: BasicBlock, _ context: some MutatingContext) {
|
func replaceBranchTarget(from fromBlock: BasicBlock, to toBlock: BasicBlock, _ context: some MutatingContext) {
|
||||||
context.notifyBranchesChanged()
|
context.notifyBranchesChanged()
|
||||||
TermInst_replaceBranchTarget(bridged, fromBlock.bridged, toBlock.bridged)
|
bridged.TermInst_replaceBranchTarget(fromBlock.bridged, toBlock.bridged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +305,6 @@ extension Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fixStackNesting(_ context: FunctionPassContext) {
|
func fixStackNesting(_ context: FunctionPassContext) {
|
||||||
PassContext_fixStackNesting(context._bridged, bridged)
|
context._bridged.fixStackNesting(bridged)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ struct ModulePassContext : Context {
|
|||||||
|
|
||||||
mutating func next() -> Function? {
|
mutating func next() -> Function? {
|
||||||
if let f = currentFunction {
|
if let f = currentFunction {
|
||||||
currentFunction = PassContext_nextFunctionInModule(f.bridged).function
|
currentFunction = BridgedPassContext.getNextFunctionInModule(f.bridged).function
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -36,14 +36,14 @@ struct ModulePassContext : Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct VTableArray : BridgedRandomAccessCollection {
|
struct VTableArray : BridgedRandomAccessCollection {
|
||||||
fileprivate let bridged: BridgedVTableArray
|
fileprivate let bridged: BridgedPassContext.VTableArray
|
||||||
|
|
||||||
var startIndex: Int { return 0 }
|
var startIndex: Int { return 0 }
|
||||||
var endIndex: Int { return bridged.count }
|
var endIndex: Int { return bridged.count }
|
||||||
|
|
||||||
subscript(_ index: Int) -> VTable {
|
subscript(_ index: Int) -> VTable {
|
||||||
assert(index >= startIndex && index < endIndex)
|
assert(index >= startIndex && index < endIndex)
|
||||||
return VTable(bridged: bridged.vTables![index])
|
return VTable(bridged: BridgedVTable(vTable: bridged.base![index]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ struct ModulePassContext : Context {
|
|||||||
|
|
||||||
mutating func next() -> WitnessTable? {
|
mutating func next() -> WitnessTable? {
|
||||||
if let t = currentTable {
|
if let t = currentTable {
|
||||||
currentTable = PassContext_nextWitnessTableInModule(t.bridged).witnessTable
|
currentTable = BridgedPassContext.getNextWitnessTableInModule(t.bridged).witnessTable
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -68,7 +68,7 @@ struct ModulePassContext : Context {
|
|||||||
|
|
||||||
mutating func next() -> DefaultWitnessTable? {
|
mutating func next() -> DefaultWitnessTable? {
|
||||||
if let t = currentTable {
|
if let t = currentTable {
|
||||||
currentTable = PassContext_nextDefaultWitnessTableInModule(t.bridged).defaultWitnessTable
|
currentTable = BridgedPassContext.getNextDefaultWitnessTableInModule(t.bridged).defaultWitnessTable
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -76,19 +76,19 @@ struct ModulePassContext : Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var functions: FunctionList {
|
var functions: FunctionList {
|
||||||
FunctionList(first: PassContext_firstFunctionInModule(_bridged).function)
|
FunctionList(first: _bridged.getFirstFunctionInModule().function)
|
||||||
}
|
}
|
||||||
|
|
||||||
var vTables: VTableArray {
|
var vTables: VTableArray {
|
||||||
VTableArray(bridged: PassContext_getVTables(_bridged))
|
VTableArray(bridged: _bridged.getVTables())
|
||||||
}
|
}
|
||||||
|
|
||||||
var witnessTables: WitnessTableList {
|
var witnessTables: WitnessTableList {
|
||||||
WitnessTableList(first: PassContext_firstWitnessTableInModule(_bridged).witnessTable)
|
WitnessTableList(first: _bridged.getFirstWitnessTableInModule().witnessTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultWitnessTables: DefaultWitnessTableList {
|
var defaultWitnessTables: DefaultWitnessTableList {
|
||||||
DefaultWitnessTableList(first: PassContext_firstDefaultWitnessTableInModule(_bridged).defaultWitnessTable)
|
DefaultWitnessTableList(first: _bridged.getFirstDefaultWitnessTableInModule().defaultWitnessTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a closure with a `PassContext` for a function, which allows to modify that function.
|
/// Run a closure with a `PassContext` for a function, which allows to modify that function.
|
||||||
@@ -96,8 +96,8 @@ struct ModulePassContext : Context {
|
|||||||
/// Only a single `transform` can be alive at the same time, i.e. it's not allowed to nest
|
/// Only a single `transform` can be alive at the same time, i.e. it's not allowed to nest
|
||||||
/// calls to `transform`.
|
/// calls to `transform`.
|
||||||
func transform(function: Function, _ runOnFunction: (FunctionPassContext) -> ()) {
|
func transform(function: Function, _ runOnFunction: (FunctionPassContext) -> ()) {
|
||||||
PassContext_beginTransformFunction(function.bridged, _bridged)
|
_bridged.beginTransformFunction(function.bridged)
|
||||||
runOnFunction(FunctionPassContext(_bridged: _bridged))
|
runOnFunction(FunctionPassContext(_bridged: _bridged))
|
||||||
PassContext_endTransformFunction(_bridged);
|
_bridged.endTransformFunction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ struct Options {
|
|||||||
let _bridged: BridgedPassContext
|
let _bridged: BridgedPassContext
|
||||||
|
|
||||||
var enableStackProtection: Bool {
|
var enableStackProtection: Bool {
|
||||||
SILOptions_enableStackProtection(_bridged) != 0
|
_bridged.enableStackProtection()
|
||||||
}
|
}
|
||||||
|
|
||||||
var enableMoveInoutStackProtection: Bool {
|
var enableMoveInoutStackProtection: Bool {
|
||||||
SILOptions_enableMoveInoutStackProtection(_bridged) != 0
|
_bridged.enableMoveInoutStackProtection()
|
||||||
}
|
}
|
||||||
|
|
||||||
func enableSimplification(for inst: Instruction) -> Bool {
|
func enableSimplification(for inst: Instruction) -> Bool {
|
||||||
SILOptions_enableSimplificationFor(inst.bridged)
|
_bridged.enableSimplificationFor(inst.bridged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public struct Builder {
|
|||||||
|
|
||||||
let insertAt: InsertionPoint
|
let insertAt: InsertionPoint
|
||||||
let location: Location
|
let location: Location
|
||||||
private let passContext: BridgedPassContext
|
private let notificationHandler: BridgedChangeNotificationHandler
|
||||||
private let notifyNewInstruction: (Instruction) -> ()
|
private let notifyNewInstruction: (Instruction) -> ()
|
||||||
|
|
||||||
private var bridged: BridgedBuilder {
|
private var bridged: BridgedBuilder {
|
||||||
@@ -40,12 +40,12 @@ public struct Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func notifyNew<I: Instruction>(_ instruction: I) -> I {
|
private func notifyNew<I: Instruction>(_ instruction: I) -> I {
|
||||||
PassContext_notifyChanges(passContext, instructionsChanged)
|
notificationHandler.notifyChanges(.instructionsChanged)
|
||||||
if instruction is FullApplySite {
|
if instruction is FullApplySite {
|
||||||
PassContext_notifyChanges(passContext, callsChanged)
|
notificationHandler.notifyChanges(.callsChanged)
|
||||||
}
|
}
|
||||||
if instruction is TermInst {
|
if instruction is TermInst {
|
||||||
PassContext_notifyChanges(passContext, branchesChanged)
|
notificationHandler.notifyChanges(.branchesChanged)
|
||||||
}
|
}
|
||||||
notifyNewInstruction(instruction)
|
notifyNewInstruction(instruction)
|
||||||
return instruction
|
return instruction
|
||||||
@@ -53,11 +53,11 @@ public struct Builder {
|
|||||||
|
|
||||||
public init(insertAt: InsertionPoint, location: Location,
|
public init(insertAt: InsertionPoint, location: Location,
|
||||||
_ notifyNewInstruction: @escaping (Instruction) -> (),
|
_ notifyNewInstruction: @escaping (Instruction) -> (),
|
||||||
_ passContext: BridgedPassContext) {
|
_ notificationHandler: BridgedChangeNotificationHandler) {
|
||||||
self.insertAt = insertAt
|
self.insertAt = insertAt
|
||||||
self.location = location;
|
self.location = location;
|
||||||
self.notifyNewInstruction = notifyNewInstruction
|
self.notifyNewInstruction = notifyNewInstruction
|
||||||
self.passContext = passContext
|
self.notificationHandler = notificationHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
public func createBuiltinBinaryFunction(name: String,
|
public func createBuiltinBinaryFunction(name: String,
|
||||||
|
|||||||
@@ -40,16 +40,7 @@ struct BridgedBasicBlock;
|
|||||||
struct BridgedSuccessorArray;
|
struct BridgedSuccessorArray;
|
||||||
struct OptionalBridgedBasicBlock;
|
struct OptionalBridgedBasicBlock;
|
||||||
|
|
||||||
enum ChangeNotificationKind {
|
void registerBridgedClass(llvm::StringRef className, SwiftMetatype metatype);
|
||||||
instructionsChanged,
|
|
||||||
callsChanged,
|
|
||||||
branchesChanged,
|
|
||||||
effectsChanged
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const void * _Nonnull opaqueCtxt;
|
|
||||||
} BridgedPassContext;
|
|
||||||
|
|
||||||
struct BridgedValue {
|
struct BridgedValue {
|
||||||
SwiftObject obj;
|
SwiftObject obj;
|
||||||
@@ -613,6 +604,12 @@ struct BridgedInstruction {
|
|||||||
return getAs<swift::CondBranchInst>()->getNumTrueArgs();
|
return getAs<swift::CondBranchInst>()->getNumTrueArgs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AllocRefInstBase_setIsStackAllocatable() const {
|
||||||
|
getAs<swift::AllocRefInstBase>()->setStackAllocatable();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void TermInst_replaceBranchTarget(BridgedBasicBlock from, BridgedBasicBlock to) const;
|
||||||
|
|
||||||
SwiftInt KeyPathInst_getNumComponents() const {
|
SwiftInt KeyPathInst_getNumComponents() const {
|
||||||
if (swift::KeyPathPattern *pattern = getAs<swift::KeyPathInst>()->getPattern()) {
|
if (swift::KeyPathPattern *pattern = getAs<swift::KeyPathInst>()->getPattern()) {
|
||||||
return (SwiftInt)pattern->getComponents().size();
|
return (SwiftInt)pattern->getComponents().size();
|
||||||
@@ -1052,17 +1049,24 @@ struct BridgedNominalTypeDecl {
|
|||||||
swift::NominalTypeDecl * _Nonnull decl;
|
swift::NominalTypeDecl * _Nonnull decl;
|
||||||
};
|
};
|
||||||
|
|
||||||
void registerBridgedClass(llvm::StringRef className, SwiftMetatype metatype);
|
// Passmanager and Context
|
||||||
|
|
||||||
SwiftInt PassContext_continueWithNextSubpassRun(BridgedPassContext passContext,
|
namespace swift {
|
||||||
OptionalBridgedInstruction inst);
|
class SwiftPassInvocation;
|
||||||
void PassContext_notifyChanges(BridgedPassContext passContext,
|
}
|
||||||
enum ChangeNotificationKind changeKind);
|
|
||||||
BridgedBasicBlock PassContext_splitBlock(BridgedInstruction bridgedInst);
|
struct BridgedChangeNotificationHandler {
|
||||||
void PassContext_eraseInstruction(BridgedPassContext passContext,
|
swift::SwiftPassInvocation * _Nonnull invocation;
|
||||||
BridgedInstruction inst);
|
|
||||||
void PassContext_eraseBlock(BridgedPassContext passContext,
|
enum class Kind {
|
||||||
BridgedBasicBlock block);
|
instructionsChanged,
|
||||||
|
callsChanged,
|
||||||
|
branchesChanged,
|
||||||
|
effectsChanged
|
||||||
|
};
|
||||||
|
|
||||||
|
void notifyChanges(Kind changeKind) const;
|
||||||
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Inline functions
|
// Inline functions
|
||||||
@@ -1115,6 +1119,10 @@ BridgedBasicBlock BridgedInstruction::BranchInst_getTargetBlock() const {
|
|||||||
return {getAs<swift::BranchInst>()->getDestBB()};
|
return {getAs<swift::BranchInst>()->getDestBB()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BridgedInstruction::TermInst_replaceBranchTarget(BridgedBasicBlock from, BridgedBasicBlock to) const {
|
||||||
|
getAs<swift::TermInst>()->replaceBranchTarget(from.getBlock(), to.getBlock());
|
||||||
|
}
|
||||||
|
|
||||||
OptionalBridgedSuccessor BridgedBasicBlock::getFirstPred() const {
|
OptionalBridgedSuccessor BridgedBasicBlock::getFirstPred() const {
|
||||||
return {getBlock()->pred_begin().getSuccessorRef()};
|
return {getBlock()->pred_begin().getSuccessorRef()};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,22 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getCount() const {
|
||||||
|
switch (kind) {
|
||||||
|
case Kind::empty: return 0;
|
||||||
|
case Kind::singleFunction: return 1;
|
||||||
|
case Kind::multipleCallees: return ((Callees *)functionOrCallees)->size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SILFunction *get(unsigned index) const {
|
||||||
|
switch (kind) {
|
||||||
|
case Kind::empty: llvm_unreachable("empty callee list");
|
||||||
|
case Kind::singleFunction: return (SILFunction *)functionOrCallees;
|
||||||
|
case Kind::multipleCallees: return ((Callees *)functionOrCallees)->operator[](index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isIncomplete() const { return incomplete; }
|
bool isIncomplete() const { return incomplete; }
|
||||||
|
|
||||||
/// Returns true if all callees are known and not external.
|
/// Returns true if all callees are known and not external.
|
||||||
|
|||||||
@@ -14,71 +14,400 @@
|
|||||||
#define SWIFT_SILOPTIMIZER_OPTIMIZERBRIDGING_H
|
#define SWIFT_SILOPTIMIZER_OPTIMIZERBRIDGING_H
|
||||||
|
|
||||||
#include "swift/SIL/SILBridging.h"
|
#include "swift/SIL/SILBridging.h"
|
||||||
|
#include "swift/SILOptimizer/PassManager/PassManager.h"
|
||||||
|
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
|
||||||
|
#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
|
||||||
|
#include "swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
|
||||||
|
#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
|
||||||
|
|
||||||
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
|
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
|
||||||
|
|
||||||
typedef struct {
|
struct BridgedPassContext;
|
||||||
BridgedFunction function;
|
|
||||||
BridgedPassContext passContext;
|
|
||||||
} BridgedFunctionPassCtxt;
|
|
||||||
|
|
||||||
typedef struct {
|
struct BridgedAliasAnalysis {
|
||||||
BridgedInstruction instruction;
|
swift::AliasAnalysis * _Nonnull aa;
|
||||||
BridgedPassContext passContext;
|
|
||||||
} BridgedInstructionPassCtxt;
|
|
||||||
|
|
||||||
typedef struct {
|
swift::MemoryBehavior getMemBehavior(BridgedInstruction inst, BridgedValue addr) const {
|
||||||
const BridgedVTable * _Nullable vTables;
|
return aa->computeMemoryBehavior(inst.getInst(), addr.getSILValue());
|
||||||
SwiftInt count;
|
}
|
||||||
} BridgedVTableArray;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef swift::MemoryBehavior (* _Nonnull GetMemEffectFn)(
|
||||||
const void * _Nonnull aliasAnalysis;
|
BridgedPassContext context, BridgedValue, BridgedInstruction);
|
||||||
} BridgedAliasAnalysis;
|
typedef bool (* _Nonnull Escaping2InstFn)(
|
||||||
|
BridgedPassContext context, BridgedValue, BridgedInstruction);
|
||||||
|
typedef bool (* _Nonnull Escaping2ValFn)(
|
||||||
|
BridgedPassContext context, BridgedValue, BridgedValue);
|
||||||
|
typedef bool (* _Nonnull Escaping2ValIntFn)(
|
||||||
|
BridgedPassContext context, BridgedValue, BridgedValue, SwiftInt);
|
||||||
|
|
||||||
typedef struct {
|
static void registerAnalysis(GetMemEffectFn getMemEffectsFn,
|
||||||
void * _Nullable bca;
|
Escaping2InstFn isObjReleasedFn,
|
||||||
} BridgedCalleeAnalysis;
|
Escaping2ValIntFn isAddrVisibleFromObjFn,
|
||||||
|
Escaping2ValFn mayPointToSameAddrFn);
|
||||||
|
};
|
||||||
|
|
||||||
typedef bool (* _Nonnull InstructionIsDeinitBarrierFn)(BridgedInstruction, BridgedCalleeAnalysis bca);
|
struct BridgedCalleeAnalysis {
|
||||||
typedef swift::MemoryBehavior (* _Nonnull CalleeAnalysisGetMemBehvaiorFn)(
|
swift::BasicCalleeAnalysis * _Nonnull ca;
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
swift::CalleeList getCallees(BridgedValue callee) const {
|
||||||
|
return ca->getCalleeListOfValue(callee.getSILValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
swift::CalleeList getDestructors(swift::SILType type, bool isExactType) const {
|
||||||
|
return ca->getDestructors(type, isExactType);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
static BridgedFunction getCallee(swift::CalleeList cl, SwiftInt index) {
|
||||||
|
return {cl.get(index)};
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef bool (* _Nonnull IsDeinitBarrierFn)(BridgedInstruction, BridgedCalleeAnalysis bca);
|
||||||
|
typedef swift::MemoryBehavior (* _Nonnull GetMemBehvaiorFn)(
|
||||||
BridgedPassContext context, BridgedInstruction apply, bool observeRetains);
|
BridgedPassContext context, BridgedInstruction apply, bool observeRetains);
|
||||||
|
|
||||||
void CalleeAnalysis_register(InstructionIsDeinitBarrierFn isDeinitBarrierFn,
|
static void registerAnalysis(IsDeinitBarrierFn isDeinitBarrierFn,
|
||||||
CalleeAnalysisGetMemBehvaiorFn getEffectsFn);
|
GetMemBehvaiorFn getEffectsFn);
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct BridgedDeadEndBlocksAnalysis {
|
||||||
void * _Nullable dea;
|
swift::DeadEndBlocks * _Nonnull deb;
|
||||||
} BridgedDeadEndBlocksAnalysis;
|
|
||||||
|
|
||||||
typedef struct {
|
bool isDeadEnd(BridgedBasicBlock block) const {
|
||||||
void * _Nullable dt;
|
return deb->isDeadEnd(block.getBlock());
|
||||||
} BridgedDomTree;
|
}
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct BridgedDomTree {
|
||||||
void * _Nullable pdt;
|
swift::DominanceInfo * _Nonnull di;
|
||||||
} BridgedPostDomTree;
|
|
||||||
|
|
||||||
typedef struct {
|
bool dominates(BridgedBasicBlock dominating, BridgedBasicBlock dominated) const {
|
||||||
void * _Nonnull opaquePtr;
|
return di->dominates(dominating.getBlock(), dominated.getBlock());
|
||||||
unsigned char kind;
|
}
|
||||||
unsigned char incomplete;
|
};
|
||||||
} BridgedCalleeList;
|
|
||||||
|
|
||||||
typedef struct {
|
struct BridgedBasicBlockSet {
|
||||||
void * _Nullable bbs;
|
swift::BasicBlockSet * _Nonnull set;
|
||||||
} BridgedBasicBlockSet;
|
|
||||||
|
|
||||||
typedef struct {
|
bool contains(BridgedBasicBlock block) const {
|
||||||
void * _Nullable nds;
|
return set->contains(block.getBlock());
|
||||||
} BridgedNodeSet;
|
}
|
||||||
|
|
||||||
typedef struct {
|
bool insert(BridgedBasicBlock block) const {
|
||||||
void * _Nullable data;
|
return set->insert(block.getBlock());
|
||||||
} BridgedSlab;
|
}
|
||||||
|
|
||||||
enum {
|
void erase(BridgedBasicBlock block) const {
|
||||||
BridgedSlabCapacity = 64 * sizeof(uintptr_t)
|
set->erase(block.getBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedFunction getFunction() const {
|
||||||
|
return {set->getFunction()};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BridgedNodeSet {
|
||||||
|
swift::NodeSet * _Nonnull set;
|
||||||
|
|
||||||
|
bool containsValue(BridgedValue value) const {
|
||||||
|
return set->contains(value.getSILValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool insertValue(BridgedValue value) const {
|
||||||
|
return set->insert(value.getSILValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
void eraseValue(BridgedValue value) const {
|
||||||
|
set->erase(value.getSILValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool containsInstruction(BridgedInstruction inst) const {
|
||||||
|
return set->contains(inst.getInst()->asSILNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool insertInstruction(BridgedInstruction inst) const {
|
||||||
|
return set->insert(inst.getInst()->asSILNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
void eraseInstruction(BridgedInstruction inst) const {
|
||||||
|
set->erase(inst.getInst()->asSILNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedFunction getFunction() const {
|
||||||
|
return {set->getFunction()};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BridgedPostDomTree {
|
||||||
|
swift::PostDominanceInfo * _Nonnull pdi;
|
||||||
|
|
||||||
|
bool postDominates(BridgedBasicBlock dominating, BridgedBasicBlock dominated) const {
|
||||||
|
return pdi->dominates(dominating.getBlock(), dominated.getBlock());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BridgedPassContext {
|
||||||
|
swift::SwiftPassInvocation * _Nonnull invocation;
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedChangeNotificationHandler asNotificationHandler() const {
|
||||||
|
return {invocation};
|
||||||
|
}
|
||||||
|
// Analysis
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedAliasAnalysis getAliasAnalysis() const {
|
||||||
|
return {invocation->getPassManager()->getAnalysis<swift::AliasAnalysis>(invocation->getFunction())};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedCalleeAnalysis getCalleeAnalysis() const {
|
||||||
|
return {invocation->getPassManager()->getAnalysis<swift::BasicCalleeAnalysis>()};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedDeadEndBlocksAnalysis getDeadEndBlocksAnalysis() const {
|
||||||
|
auto *dba = invocation->getPassManager()->getAnalysis<swift::DeadEndBlocksAnalysis>();
|
||||||
|
return {dba->get(invocation->getFunction())};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedDomTree getDomTree() const {
|
||||||
|
auto *da = invocation->getPassManager()->getAnalysis<swift::DominanceAnalysis>();
|
||||||
|
return {da->get(invocation->getFunction())};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedPostDomTree getPostDomTree() const {
|
||||||
|
auto *pda = invocation->getPassManager()->getAnalysis<swift::PostDominanceAnalysis>();
|
||||||
|
return {pda->get(invocation->getFunction())};
|
||||||
|
}
|
||||||
|
|
||||||
|
// SIL modifications
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedBasicBlock splitBlock(BridgedInstruction bridgedInst) const {
|
||||||
|
auto *inst = bridgedInst.getInst();
|
||||||
|
auto *block = inst->getParent();
|
||||||
|
return {block->split(inst->getIterator())};
|
||||||
|
}
|
||||||
|
|
||||||
|
void eraseInstruction(BridgedInstruction inst) const {
|
||||||
|
invocation->eraseInstruction(inst.getInst());
|
||||||
|
}
|
||||||
|
|
||||||
|
void eraseBlock(BridgedBasicBlock block) const {
|
||||||
|
block.getBlock()->eraseFromParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tryDeleteDeadClosure(BridgedInstruction closure) const;
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedValue getSILUndef(swift::SILType type) const {
|
||||||
|
return {swift::SILUndef::get(type, *invocation->getFunction())};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedBasicBlockSet allocBasicBlockSet() const {
|
||||||
|
return {invocation->allocBlockSet()};
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeBasicBlockSet(BridgedBasicBlockSet set) const {
|
||||||
|
invocation->freeBlockSet(set.set);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
BridgedNodeSet allocNodeSet() const {
|
||||||
|
return {invocation->allocNodeSet()};
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeNodeSet(BridgedNodeSet set) const {
|
||||||
|
invocation->freeNodeSet(set.set);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack nesting
|
||||||
|
|
||||||
|
void notifyInvalidatedStackNesting() const {
|
||||||
|
invocation->setNeedFixStackNesting(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getNeedFixStackNesting() const {
|
||||||
|
return invocation->getNeedFixStackNesting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixStackNesting(BridgedFunction function) const;
|
||||||
|
|
||||||
|
// Slabs
|
||||||
|
|
||||||
|
struct Slab {
|
||||||
|
swift::FixedSizeSlabPayload * _Nullable data = nullptr;
|
||||||
|
|
||||||
|
static SwiftInt getCapacity() {
|
||||||
|
return (SwiftInt)swift::FixedSizeSlabPayload::capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slab(swift::FixedSizeSlab * _Nullable slab) {
|
||||||
|
if (slab) {
|
||||||
|
data = slab;
|
||||||
|
assert((void *)data == slab->dataFor<void>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swift::FixedSizeSlab * _Nullable getSlab() const {
|
||||||
|
if (data)
|
||||||
|
return static_cast<swift::FixedSizeSlab *>(data);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
Slab getNext() const {
|
||||||
|
return &*std::next(getSlab()->getIterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
Slab getPrevious() const {
|
||||||
|
return &*std::prev(getSlab()->getIterator());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
Slab allocSlab(Slab afterSlab) const {
|
||||||
|
return invocation->allocSlab(afterSlab.getSlab());
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
Slab freeSlab(Slab slab) const {
|
||||||
|
return invocation->freeSlab(slab.getSlab());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access SIL module data structures
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
OptionalBridgedFunction getFirstFunctionInModule() const {
|
||||||
|
swift::SILModule *mod = invocation->getPassManager()->getModule();
|
||||||
|
if (mod->getFunctions().empty())
|
||||||
|
return {nullptr};
|
||||||
|
return {&*mod->getFunctions().begin()};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
static OptionalBridgedFunction getNextFunctionInModule(BridgedFunction function) {
|
||||||
|
auto *f = function.getFunction();
|
||||||
|
auto nextIter = std::next(f->getIterator());
|
||||||
|
if (nextIter == f->getModule().getFunctions().end())
|
||||||
|
return {nullptr};
|
||||||
|
return {&*nextIter};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VTableArray {
|
||||||
|
swift::SILVTable * const _Nonnull * _Nullable base;
|
||||||
|
SwiftInt count;
|
||||||
|
};
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
VTableArray getVTables() const {
|
||||||
|
swift::SILModule *mod = invocation->getPassManager()->getModule();
|
||||||
|
auto vTables = mod->getVTables();
|
||||||
|
return {vTables.data(), (SwiftInt)vTables.size()};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
OptionalBridgedWitnessTable getFirstWitnessTableInModule() const {
|
||||||
|
swift::SILModule *mod = invocation->getPassManager()->getModule();
|
||||||
|
if (mod->getWitnessTables().empty())
|
||||||
|
return {nullptr};
|
||||||
|
return {&*mod->getWitnessTables().begin()};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
static OptionalBridgedWitnessTable getNextWitnessTableInModule(BridgedWitnessTable table) {
|
||||||
|
auto *t = table.table;
|
||||||
|
auto nextIter = std::next(t->getIterator());
|
||||||
|
if (nextIter == t->getModule().getWitnessTables().end())
|
||||||
|
return {nullptr};
|
||||||
|
return {&*nextIter};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
OptionalBridgedDefaultWitnessTable getFirstDefaultWitnessTableInModule() const {
|
||||||
|
swift::SILModule *mod = invocation->getPassManager()->getModule();
|
||||||
|
if (mod->getDefaultWitnessTables().empty())
|
||||||
|
return {nullptr};
|
||||||
|
return {&*mod->getDefaultWitnessTables().begin()};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
static OptionalBridgedDefaultWitnessTable getNextDefaultWitnessTableInModule(BridgedDefaultWitnessTable table) {
|
||||||
|
auto *t = table.table;
|
||||||
|
auto nextIter = std::next(t->getIterator());
|
||||||
|
if (nextIter == t->getModule().getDefaultWitnessTables().end())
|
||||||
|
return {nullptr};
|
||||||
|
return {&*nextIter};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
OptionalBridgedFunction loadFunction(llvm::StringRef name) const {
|
||||||
|
swift::SILModule *mod = invocation->getPassManager()->getModule();
|
||||||
|
return {mod->loadFunction(name, swift::SILModule::LinkingMode::LinkNormal)};
|
||||||
|
}
|
||||||
|
|
||||||
|
SWIFT_IMPORT_UNSAFE
|
||||||
|
swift::SubstitutionMap getContextSubstitutionMap(swift::SILType type) const {
|
||||||
|
auto *ntd = type.getASTType()->getAnyNominal();
|
||||||
|
auto *mod = invocation->getPassManager()->getModule()->getSwiftModule();
|
||||||
|
return type.getASTType()->getContextSubstitutionMap(mod, ntd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passmanager housekeeping
|
||||||
|
|
||||||
|
void beginTransformFunction(BridgedFunction function) const {
|
||||||
|
invocation->beginTransformFunction(function.getFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
void endTransformFunction() const {
|
||||||
|
invocation->endTransformFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool continueWithNextSubpassRun(OptionalBridgedInstruction inst) const {
|
||||||
|
swift::SILPassManager *pm = invocation->getPassManager();
|
||||||
|
return pm->continueWithNextSubpassRun(inst.getInst(),
|
||||||
|
invocation->getFunction(),
|
||||||
|
invocation->getTransform());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options
|
||||||
|
|
||||||
|
bool enableStackProtection() const {
|
||||||
|
swift::SILModule *mod = invocation->getPassManager()->getModule();
|
||||||
|
return mod->getOptions().EnableStackProtection;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enableMoveInoutStackProtection() const {
|
||||||
|
swift::SILModule *mod = invocation->getPassManager()->getModule();
|
||||||
|
return mod->getOptions().EnableMoveInoutStackProtection;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enableSimplificationFor(BridgedInstruction inst) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Pass registration
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
struct BridgedFunctionPassCtxt {
|
||||||
|
BridgedFunction function;
|
||||||
|
BridgedPassContext passContext;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
struct BridgedInstructionPassCtxt {
|
||||||
|
BridgedInstruction instruction;
|
||||||
|
BridgedPassContext passContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (* _Nonnull BridgedModulePassRunFn)(BridgedPassContext);
|
typedef void (* _Nonnull BridgedModulePassRunFn)(BridgedPassContext);
|
||||||
@@ -92,124 +421,6 @@ void SILPassManager_registerFunctionPass(llvm::StringRef name,
|
|||||||
void SILCombine_registerInstructionPass(llvm::StringRef instClassName,
|
void SILCombine_registerInstructionPass(llvm::StringRef instClassName,
|
||||||
BridgedInstructionPassRunFn runFn);
|
BridgedInstructionPassRunFn runFn);
|
||||||
|
|
||||||
BridgedAliasAnalysis PassContext_getAliasAnalysis(BridgedPassContext context);
|
|
||||||
|
|
||||||
swift::MemoryBehavior AliasAnalysis_getMemBehavior(BridgedAliasAnalysis aa,
|
|
||||||
BridgedInstruction inst,
|
|
||||||
BridgedValue addr);
|
|
||||||
|
|
||||||
BridgedCalleeAnalysis PassContext_getCalleeAnalysis(BridgedPassContext context);
|
|
||||||
|
|
||||||
BridgedCalleeList CalleeAnalysis_getCallees(BridgedCalleeAnalysis calleeAnalysis,
|
|
||||||
BridgedValue callee);
|
|
||||||
BridgedCalleeList CalleeAnalysis_getDestructors(BridgedCalleeAnalysis calleeAnalysis,
|
|
||||||
swift::SILType type,
|
|
||||||
SwiftInt isExactType);
|
|
||||||
SwiftInt BridgedFunctionArray_size(BridgedCalleeList callees);
|
|
||||||
BridgedFunction BridgedFunctionArray_get(BridgedCalleeList callees,
|
|
||||||
SwiftInt index);
|
|
||||||
|
|
||||||
BridgedDeadEndBlocksAnalysis
|
|
||||||
PassContext_getDeadEndBlocksAnalysis(BridgedPassContext context);
|
|
||||||
|
|
||||||
SwiftInt DeadEndBlocksAnalysis_isDeadEnd(BridgedDeadEndBlocksAnalysis debAnalysis,
|
|
||||||
BridgedBasicBlock);
|
|
||||||
|
|
||||||
BridgedDomTree PassContext_getDomTree(BridgedPassContext context);
|
|
||||||
|
|
||||||
SwiftInt DominatorTree_dominates(BridgedDomTree domTree,
|
|
||||||
BridgedBasicBlock dominating,
|
|
||||||
BridgedBasicBlock dominated);
|
|
||||||
|
|
||||||
BridgedPostDomTree PassContext_getPostDomTree(BridgedPassContext context);
|
|
||||||
|
|
||||||
SwiftInt PostDominatorTree_postDominates(BridgedPostDomTree pdomTree,
|
|
||||||
BridgedBasicBlock dominating,
|
|
||||||
BridgedBasicBlock dominated);
|
|
||||||
|
|
||||||
typedef swift::MemoryBehavior (* _Nonnull AliasAnalysisGetMemEffectFn)(
|
|
||||||
BridgedPassContext context, BridgedValue, BridgedInstruction);
|
|
||||||
typedef bool (* _Nonnull AliasAnalysisEscaping2InstFn)(
|
|
||||||
BridgedPassContext context, BridgedValue, BridgedInstruction);
|
|
||||||
typedef bool (* _Nonnull AliasAnalysisEscaping2ValFn)(
|
|
||||||
BridgedPassContext context, BridgedValue, BridgedValue);
|
|
||||||
typedef bool (* _Nonnull AliasAnalysisEscaping2ValIntFn)(
|
|
||||||
BridgedPassContext context, BridgedValue, BridgedValue, SwiftInt);
|
|
||||||
|
|
||||||
void AliasAnalysis_register(AliasAnalysisGetMemEffectFn getMemEffectsFn,
|
|
||||||
AliasAnalysisEscaping2InstFn isObjReleasedFn,
|
|
||||||
AliasAnalysisEscaping2ValIntFn isAddrVisibleFromObjFn,
|
|
||||||
AliasAnalysisEscaping2ValFn mayPointToSameAddrFn);
|
|
||||||
|
|
||||||
BridgedSlab PassContext_getNextSlab(BridgedSlab slab);
|
|
||||||
BridgedSlab PassContext_getPreviousSlab(BridgedSlab slab);
|
|
||||||
BridgedSlab PassContext_allocSlab(BridgedPassContext passContext,
|
|
||||||
BridgedSlab afterSlab);
|
|
||||||
BridgedSlab PassContext_freeSlab(BridgedPassContext passContext,
|
|
||||||
BridgedSlab slab);
|
|
||||||
|
|
||||||
bool PassContext_tryDeleteDeadClosure(BridgedPassContext context, BridgedInstruction closure);
|
|
||||||
|
|
||||||
void PassContext_notifyInvalidatedStackNesting(BridgedPassContext context);
|
|
||||||
bool PassContext_getNeedFixStackNesting(BridgedPassContext context);
|
|
||||||
void PassContext_fixStackNesting(BridgedPassContext context,
|
|
||||||
BridgedFunction function);
|
|
||||||
|
|
||||||
BridgedBasicBlockSet PassContext_allocBasicBlockSet(BridgedPassContext context);
|
|
||||||
void PassContext_freeBasicBlockSet(BridgedPassContext context,
|
|
||||||
BridgedBasicBlockSet set);
|
|
||||||
SwiftInt BasicBlockSet_contains(BridgedBasicBlockSet set, BridgedBasicBlock block);
|
|
||||||
SwiftInt BasicBlockSet_insert(BridgedBasicBlockSet set, BridgedBasicBlock block);
|
|
||||||
void BasicBlockSet_erase(BridgedBasicBlockSet set, BridgedBasicBlock block);
|
|
||||||
BridgedFunction BasicBlockSet_getFunction(BridgedBasicBlockSet set);
|
|
||||||
|
|
||||||
BridgedNodeSet PassContext_allocNodeSet(BridgedPassContext context);
|
|
||||||
void PassContext_freeNodeSet(BridgedPassContext context,
|
|
||||||
BridgedNodeSet set);
|
|
||||||
SwiftInt NodeSet_containsValue(BridgedNodeSet set, BridgedValue value);
|
|
||||||
SwiftInt NodeSet_insertValue(BridgedNodeSet set, BridgedValue value);
|
|
||||||
void NodeSet_eraseValue(BridgedNodeSet set, BridgedValue value);
|
|
||||||
SwiftInt NodeSet_containsInstruction(BridgedNodeSet set, BridgedInstruction inst);
|
|
||||||
SwiftInt NodeSet_insertInstruction(BridgedNodeSet set, BridgedInstruction inst);
|
|
||||||
void NodeSet_eraseInstruction(BridgedNodeSet set, BridgedInstruction inst);
|
|
||||||
BridgedFunction NodeSet_getFunction(BridgedNodeSet set);
|
|
||||||
|
|
||||||
void AllocRefInstBase_setIsStackAllocatable(BridgedInstruction arb);
|
|
||||||
|
|
||||||
void TermInst_replaceBranchTarget(BridgedInstruction term, BridgedBasicBlock from,
|
|
||||||
BridgedBasicBlock to);
|
|
||||||
|
|
||||||
swift::SubstitutionMap
|
|
||||||
PassContext_getContextSubstitutionMap(BridgedPassContext context,
|
|
||||||
swift::SILType bridgedType);
|
|
||||||
|
|
||||||
void PassContext_beginTransformFunction(BridgedFunction function,
|
|
||||||
BridgedPassContext ctxt);
|
|
||||||
void PassContext_endTransformFunction(BridgedPassContext ctxt);
|
|
||||||
|
|
||||||
OptionalBridgedFunction
|
|
||||||
PassContext_firstFunctionInModule(BridgedPassContext context);
|
|
||||||
OptionalBridgedFunction
|
|
||||||
PassContext_nextFunctionInModule(BridgedFunction function);
|
|
||||||
BridgedVTableArray PassContext_getVTables(BridgedPassContext context);
|
|
||||||
OptionalBridgedWitnessTable
|
|
||||||
PassContext_firstWitnessTableInModule(BridgedPassContext context);
|
|
||||||
OptionalBridgedWitnessTable
|
|
||||||
PassContext_nextWitnessTableInModule(BridgedWitnessTable table);
|
|
||||||
OptionalBridgedDefaultWitnessTable
|
|
||||||
PassContext_firstDefaultWitnessTableInModule(BridgedPassContext context);
|
|
||||||
OptionalBridgedDefaultWitnessTable
|
|
||||||
PassContext_nextDefaultWitnessTableInModule(BridgedDefaultWitnessTable table);
|
|
||||||
|
|
||||||
OptionalBridgedFunction
|
|
||||||
PassContext_loadFunction(BridgedPassContext context, llvm::StringRef name);
|
|
||||||
|
|
||||||
SwiftInt SILOptions_enableStackProtection(BridgedPassContext context);
|
|
||||||
SwiftInt SILOptions_enableMoveInoutStackProtection(BridgedPassContext context);
|
|
||||||
bool SILOptions_enableSimplificationFor(BridgedInstruction inst);
|
|
||||||
|
|
||||||
BridgedValue SILUndef_get(swift::SILType type, BridgedPassContext context);
|
|
||||||
|
|
||||||
SWIFT_END_NULLABILITY_ANNOTATIONS
|
SWIFT_END_NULLABILITY_ANNOTATIONS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -521,10 +521,10 @@ bool AliasAnalysis::typesMayAlias(SILType T1, SILType T2,
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Bridging functions.
|
// Bridging functions.
|
||||||
static AliasAnalysisGetMemEffectFn getMemEffectsFunction = nullptr;
|
static BridgedAliasAnalysis::GetMemEffectFn getMemEffectsFunction = nullptr;
|
||||||
static AliasAnalysisEscaping2InstFn isObjReleasedFunction = nullptr;
|
static BridgedAliasAnalysis::Escaping2InstFn isObjReleasedFunction = nullptr;
|
||||||
static AliasAnalysisEscaping2ValIntFn isAddrVisibleFromObjFunction = nullptr;
|
static BridgedAliasAnalysis::Escaping2ValIntFn isAddrVisibleFromObjFunction = nullptr;
|
||||||
static AliasAnalysisEscaping2ValFn canReferenceSameFieldFunction = nullptr;
|
static BridgedAliasAnalysis::Escaping2ValFn canReferenceSameFieldFunction = nullptr;
|
||||||
|
|
||||||
/// The main AA entry point. Performs various analyses on V1, V2 in an attempt
|
/// The main AA entry point. Performs various analyses on V1, V2 in an attempt
|
||||||
/// to disambiguate the two values.
|
/// to disambiguate the two values.
|
||||||
@@ -701,21 +701,10 @@ SILAnalysis *swift::createAliasAnalysis(SILModule *M) {
|
|||||||
// Swift Bridging
|
// Swift Bridging
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
inline AliasAnalysis *castToAliasAnalysis(BridgedAliasAnalysis aa) {
|
void BridgedAliasAnalysis::registerAnalysis(GetMemEffectFn getMemEffectsFn,
|
||||||
return const_cast<AliasAnalysis *>(
|
Escaping2InstFn isObjReleasedFn,
|
||||||
static_cast<const AliasAnalysis *>(aa.aliasAnalysis));
|
Escaping2ValIntFn isAddrVisibleFromObjFn,
|
||||||
}
|
Escaping2ValFn canReferenceSameFieldFn) {
|
||||||
|
|
||||||
MemoryBehavior AliasAnalysis_getMemBehavior(BridgedAliasAnalysis aa,
|
|
||||||
BridgedInstruction inst,
|
|
||||||
BridgedValue addr) {
|
|
||||||
return castToAliasAnalysis(aa)->computeMemoryBehavior(inst.getInst(), addr.getSILValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AliasAnalysis_register(AliasAnalysisGetMemEffectFn getMemEffectsFn,
|
|
||||||
AliasAnalysisEscaping2InstFn isObjReleasedFn,
|
|
||||||
AliasAnalysisEscaping2ValIntFn isAddrVisibleFromObjFn,
|
|
||||||
AliasAnalysisEscaping2ValFn canReferenceSameFieldFn) {
|
|
||||||
getMemEffectsFunction = getMemEffectsFn;
|
getMemEffectsFunction = getMemEffectsFn;
|
||||||
isObjReleasedFunction = isObjReleasedFn;
|
isObjReleasedFunction = isObjReleasedFn;
|
||||||
isAddrVisibleFromObjFunction = isAddrVisibleFromObjFn;
|
isAddrVisibleFromObjFunction = isAddrVisibleFromObjFn;
|
||||||
|
|||||||
@@ -336,42 +336,11 @@ void BasicCalleeAnalysis::print(llvm::raw_ostream &os) const {
|
|||||||
// Swift Bridging
|
// Swift Bridging
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
BridgedCalleeList CalleeAnalysis_getCallees(BridgedCalleeAnalysis calleeAnalysis,
|
static BridgedCalleeAnalysis::IsDeinitBarrierFn instructionIsDeinitBarrierFunction;
|
||||||
BridgedValue callee) {
|
static BridgedCalleeAnalysis::GetMemBehvaiorFn getMemBehvaiorFunction = nullptr;
|
||||||
BasicCalleeAnalysis *bca = static_cast<BasicCalleeAnalysis *>(calleeAnalysis.bca);
|
|
||||||
CalleeList cl = bca->getCalleeListOfValue(callee.getSILValue());
|
|
||||||
return {cl.getOpaquePtr(), cl.getOpaqueKind(), cl.isIncomplete()};
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedCalleeList CalleeAnalysis_getDestructors(BridgedCalleeAnalysis calleeAnalysis,
|
void BridgedCalleeAnalysis::registerAnalysis(IsDeinitBarrierFn instructionIsDeinitBarrierFn,
|
||||||
SILType type,
|
GetMemBehvaiorFn getMemBehvaiorFn) {
|
||||||
SwiftInt isExactType) {
|
|
||||||
BasicCalleeAnalysis *bca = static_cast<BasicCalleeAnalysis *>(calleeAnalysis.bca);
|
|
||||||
CalleeList cl = bca->getDestructors(type, isExactType != 0);
|
|
||||||
return {cl.getOpaquePtr(), cl.getOpaqueKind(), cl.isIncomplete()};
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt BridgedFunctionArray_size(BridgedCalleeList callees) {
|
|
||||||
CalleeList cl = CalleeList::fromOpaque(callees.opaquePtr, callees.kind,
|
|
||||||
callees.incomplete);
|
|
||||||
return cl.end() - cl.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedFunction BridgedFunctionArray_get(BridgedCalleeList callees,
|
|
||||||
SwiftInt index) {
|
|
||||||
CalleeList cl = CalleeList::fromOpaque(callees.opaquePtr, callees.kind,
|
|
||||||
callees.incomplete);
|
|
||||||
auto iter = cl.begin() + index;
|
|
||||||
assert(index >= 0 && iter < cl.end());
|
|
||||||
return {*iter};
|
|
||||||
}
|
|
||||||
|
|
||||||
static InstructionIsDeinitBarrierFn instructionIsDeinitBarrierFunction;
|
|
||||||
static CalleeAnalysisGetMemBehvaiorFn getMemBehvaiorFunction = nullptr;
|
|
||||||
|
|
||||||
void CalleeAnalysis_register(
|
|
||||||
InstructionIsDeinitBarrierFn instructionIsDeinitBarrierFn,
|
|
||||||
CalleeAnalysisGetMemBehvaiorFn getMemBehvaiorFn) {
|
|
||||||
instructionIsDeinitBarrierFunction = instructionIsDeinitBarrierFn;
|
instructionIsDeinitBarrierFunction = instructionIsDeinitBarrierFn;
|
||||||
getMemBehvaiorFunction = getMemBehvaiorFn;
|
getMemBehvaiorFunction = getMemBehvaiorFn;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,13 +56,3 @@ void DeadEndBlocksAnalysis::verify(DeadEndBlocks *deBlocks) const {
|
|||||||
SILAnalysis *swift::createDeadEndBlocksAnalysis(SILModule *) {
|
SILAnalysis *swift::createDeadEndBlocksAnalysis(SILModule *) {
|
||||||
return new DeadEndBlocksAnalysis();
|
return new DeadEndBlocksAnalysis();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Swift Bridging
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
SwiftInt DeadEndBlocksAnalysis_isDeadEnd(BridgedDeadEndBlocksAnalysis debAnalysis,
|
|
||||||
BridgedBasicBlock block) {
|
|
||||||
auto *dea = static_cast<DeadEndBlocks *>(debAnalysis.dea);
|
|
||||||
return dea->isDeadEnd(block.getBlock());
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1256,9 +1256,6 @@ void SILPassManager::viewCallGraph() {
|
|||||||
// SwiftPassInvocation
|
// SwiftPassInvocation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static_assert(BridgedSlabCapacity == FixedSizeSlab::capacity,
|
|
||||||
"wrong bridged slab capacity");
|
|
||||||
|
|
||||||
FixedSizeSlab *SwiftPassInvocation::allocSlab(FixedSizeSlab *afterSlab) {
|
FixedSizeSlab *SwiftPassInvocation::allocSlab(FixedSizeSlab *afterSlab) {
|
||||||
FixedSizeSlab *slab = passManager->getModule()->allocSlab();
|
FixedSizeSlab *slab = passManager->getModule()->allocSlab();
|
||||||
if (afterSlab) {
|
if (afterSlab) {
|
||||||
@@ -1393,333 +1390,42 @@ void SwiftPassInvocation::endTransformFunction() {
|
|||||||
// Swift Bridging
|
// Swift Bridging
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
inline SwiftPassInvocation *castToPassInvocation(BridgedPassContext ctxt) {
|
void BridgedChangeNotificationHandler::notifyChanges(Kind changeKind) const {
|
||||||
return const_cast<SwiftPassInvocation *>(
|
|
||||||
static_cast<const SwiftPassInvocation *>(ctxt.opaqueCtxt));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline FixedSizeSlab *castToSlab(BridgedSlab slab) {
|
|
||||||
if (slab.data)
|
|
||||||
return static_cast<FixedSizeSlab *>((FixedSizeSlabPayload *)slab.data);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline BridgedSlab toBridgedSlab(FixedSizeSlab *slab) {
|
|
||||||
if (slab) {
|
|
||||||
FixedSizeSlabPayload *payload = slab;
|
|
||||||
assert((void *)payload == slab->dataFor<void>());
|
|
||||||
return {payload};
|
|
||||||
}
|
|
||||||
return {nullptr};
|
|
||||||
}
|
|
||||||
|
|
||||||
inline BasicBlockSet *castToBlockSet(BridgedBasicBlockSet blockSet) {
|
|
||||||
return static_cast<BasicBlockSet *>(blockSet.bbs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline NodeSet *castToNodeSet(BridgedNodeSet nodeSet) {
|
|
||||||
return static_cast<NodeSet *>(nodeSet.nds);
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedSlab PassContext_getNextSlab(BridgedSlab slab) {
|
|
||||||
return toBridgedSlab(&*std::next(castToSlab(slab)->getIterator()));
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedSlab PassContext_getPreviousSlab(BridgedSlab slab) {
|
|
||||||
return toBridgedSlab(&*std::prev(castToSlab(slab)->getIterator()));
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedSlab PassContext_allocSlab(BridgedPassContext passContext,
|
|
||||||
BridgedSlab afterSlab) {
|
|
||||||
auto *inv = castToPassInvocation(passContext);
|
|
||||||
return toBridgedSlab(inv->allocSlab(castToSlab(afterSlab)));
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedSlab PassContext_freeSlab(BridgedPassContext passContext,
|
|
||||||
BridgedSlab slab) {
|
|
||||||
auto *inv = castToPassInvocation(passContext);
|
|
||||||
return toBridgedSlab(inv->freeSlab(castToSlab(slab)));
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt PassContext_continueWithNextSubpassRun(BridgedPassContext passContext,
|
|
||||||
OptionalBridgedInstruction inst) {
|
|
||||||
SwiftPassInvocation *inv = castToPassInvocation(passContext);
|
|
||||||
SILInstruction *i = inst.getInst();
|
|
||||||
return inv->getPassManager()->continueWithNextSubpassRun(i,
|
|
||||||
inv->getFunction(), inv->getTransform()) ? 1: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassContext_notifyChanges(BridgedPassContext passContext,
|
|
||||||
enum ChangeNotificationKind changeKind) {
|
|
||||||
SwiftPassInvocation *inv = castToPassInvocation(passContext);
|
|
||||||
switch (changeKind) {
|
switch (changeKind) {
|
||||||
case instructionsChanged:
|
case Kind::instructionsChanged:
|
||||||
inv->notifyChanges(SILAnalysis::InvalidationKind::Instructions);
|
invocation->notifyChanges(SILAnalysis::InvalidationKind::Instructions);
|
||||||
break;
|
break;
|
||||||
case callsChanged:
|
case Kind::callsChanged:
|
||||||
inv->notifyChanges(SILAnalysis::InvalidationKind::CallsAndInstructions);
|
invocation->notifyChanges(SILAnalysis::InvalidationKind::CallsAndInstructions);
|
||||||
break;
|
break;
|
||||||
case branchesChanged:
|
case Kind::branchesChanged:
|
||||||
inv->notifyChanges(SILAnalysis::InvalidationKind::BranchesAndInstructions);
|
invocation->notifyChanges(SILAnalysis::InvalidationKind::BranchesAndInstructions);
|
||||||
break;
|
break;
|
||||||
case effectsChanged:
|
case Kind::effectsChanged:
|
||||||
inv->notifyChanges(SILAnalysis::InvalidationKind::Effects);
|
invocation->notifyChanges(SILAnalysis::InvalidationKind::Effects);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BridgedBasicBlock PassContext_splitBlock(BridgedInstruction bridgedInst) {
|
bool BridgedPassContext::tryDeleteDeadClosure(BridgedInstruction closure) const {
|
||||||
SILInstruction *inst = bridgedInst.getInst();
|
return ::tryDeleteDeadClosure(closure.getAs<SingleValueInstruction>(), InstModCallbacks());
|
||||||
SILBasicBlock *block = inst->getParent();
|
|
||||||
return {block->split(inst->getIterator())};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PassContext_eraseInstruction(BridgedPassContext passContext,
|
void BridgedPassContext::fixStackNesting(BridgedFunction function) const {
|
||||||
BridgedInstruction inst) {
|
|
||||||
castToPassInvocation(passContext)->eraseInstruction(inst.getInst());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassContext_eraseBlock(BridgedPassContext passContext,
|
|
||||||
BridgedBasicBlock block) {
|
|
||||||
block.getBlock()->eraseFromParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PassContext_tryDeleteDeadClosure(BridgedPassContext context, BridgedInstruction closure) {
|
|
||||||
return tryDeleteDeadClosure(closure.getAs<SingleValueInstruction>(), InstModCallbacks());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassContext_notifyInvalidatedStackNesting(BridgedPassContext context) {
|
|
||||||
castToPassInvocation(context)->setNeedFixStackNesting(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PassContext_getNeedFixStackNesting(BridgedPassContext context) {
|
|
||||||
return castToPassInvocation(context)->getNeedFixStackNesting();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassContext_fixStackNesting(BridgedPassContext passContext,
|
|
||||||
BridgedFunction function) {
|
|
||||||
switch (StackNesting::fixNesting(function.getFunction())) {
|
switch (StackNesting::fixNesting(function.getFunction())) {
|
||||||
case StackNesting::Changes::None:
|
case StackNesting::Changes::None:
|
||||||
break;
|
break;
|
||||||
case StackNesting::Changes::Instructions:
|
case StackNesting::Changes::Instructions:
|
||||||
PassContext_notifyChanges(passContext, instructionsChanged);
|
invocation->notifyChanges(SILAnalysis::InvalidationKind::Instructions);
|
||||||
break;
|
break;
|
||||||
case StackNesting::Changes::CFG:
|
case StackNesting::Changes::CFG:
|
||||||
PassContext_notifyChanges(passContext, branchesChanged);
|
invocation->notifyChanges(SILAnalysis::InvalidationKind::BranchesAndInstructions);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
castToPassInvocation(passContext)->setNeedFixStackNesting(false);
|
invocation->setNeedFixStackNesting(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
BridgedAliasAnalysis PassContext_getAliasAnalysis(BridgedPassContext context) {
|
bool BridgedPassContext::enableSimplificationFor(BridgedInstruction inst) const {
|
||||||
SwiftPassInvocation *invocation = castToPassInvocation(context);
|
|
||||||
SILPassManager *pm = invocation->getPassManager();
|
|
||||||
return {pm->getAnalysis<AliasAnalysis>(invocation->getFunction())};
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedCalleeAnalysis
|
|
||||||
PassContext_getCalleeAnalysis(BridgedPassContext context) {
|
|
||||||
SILPassManager *pm = castToPassInvocation(context)->getPassManager();
|
|
||||||
return {pm->getAnalysis<BasicCalleeAnalysis>()};
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedDeadEndBlocksAnalysis
|
|
||||||
PassContext_getDeadEndBlocksAnalysis(BridgedPassContext context) {
|
|
||||||
SwiftPassInvocation *invocation = castToPassInvocation(context);
|
|
||||||
SILPassManager *pm = invocation->getPassManager();
|
|
||||||
return {pm->getAnalysis<DeadEndBlocksAnalysis>(invocation->getFunction())};
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedDomTree PassContext_getDomTree(BridgedPassContext context) {
|
|
||||||
SwiftPassInvocation *invocation = castToPassInvocation(context);
|
|
||||||
SILPassManager *pm = invocation->getPassManager();
|
|
||||||
return {pm->getAnalysis<DominanceAnalysis>(invocation->getFunction())};
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt DominatorTree_dominates(BridgedDomTree domTree,
|
|
||||||
BridgedBasicBlock dominating,
|
|
||||||
BridgedBasicBlock dominated) {
|
|
||||||
DominanceInfo *di = static_cast<DominanceInfo *>(domTree.dt);
|
|
||||||
return di->dominates(dominating.getBlock(), dominated.getBlock()) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedPostDomTree PassContext_getPostDomTree(BridgedPassContext context) {
|
|
||||||
SwiftPassInvocation *invocation = castToPassInvocation(context);
|
|
||||||
SILPassManager *pm = invocation->getPassManager();
|
|
||||||
return {pm->getAnalysis<PostDominanceAnalysis>(invocation->getFunction())};
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt PostDominatorTree_postDominates(BridgedPostDomTree pdomTree,
|
|
||||||
BridgedBasicBlock dominating,
|
|
||||||
BridgedBasicBlock dominated) {
|
|
||||||
auto *pdi = static_cast<PostDominanceInfo *>(pdomTree.pdt);
|
|
||||||
return pdi->dominates(dominating.getBlock(), dominated.getBlock()) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedBasicBlockSet PassContext_allocBasicBlockSet(BridgedPassContext context) {
|
|
||||||
return {castToPassInvocation(context)->allocBlockSet()};
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassContext_freeBasicBlockSet(BridgedPassContext context,
|
|
||||||
BridgedBasicBlockSet set) {
|
|
||||||
castToPassInvocation(context)->freeBlockSet(castToBlockSet(set));
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt BasicBlockSet_contains(BridgedBasicBlockSet set, BridgedBasicBlock block) {
|
|
||||||
return castToBlockSet(set)->contains(block.getBlock()) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt BasicBlockSet_insert(BridgedBasicBlockSet set, BridgedBasicBlock block) {
|
|
||||||
return castToBlockSet(set)->insert(block.getBlock()) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BasicBlockSet_erase(BridgedBasicBlockSet set, BridgedBasicBlock block) {
|
|
||||||
castToBlockSet(set)->erase(block.getBlock());
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedFunction BasicBlockSet_getFunction(BridgedBasicBlockSet set) {
|
|
||||||
return {castToBlockSet(set)->getFunction()};
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedNodeSet PassContext_allocNodeSet(BridgedPassContext context) {
|
|
||||||
return {castToPassInvocation(context)->allocNodeSet()};
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassContext_freeNodeSet(BridgedPassContext context,
|
|
||||||
BridgedNodeSet set) {
|
|
||||||
castToPassInvocation(context)->freeNodeSet(castToNodeSet(set));
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt NodeSet_containsValue(BridgedNodeSet set, BridgedValue value) {
|
|
||||||
return castToNodeSet(set)->contains(value.getSILValue()) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt NodeSet_insertValue(BridgedNodeSet set, BridgedValue value) {
|
|
||||||
return castToNodeSet(set)->insert(value.getSILValue()) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeSet_eraseValue(BridgedNodeSet set, BridgedValue value) {
|
|
||||||
castToNodeSet(set)->erase(value.getSILValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt NodeSet_containsInstruction(BridgedNodeSet set, BridgedInstruction inst) {
|
|
||||||
return castToNodeSet(set)->contains(inst.getInst()->asSILNode()) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt NodeSet_insertInstruction(BridgedNodeSet set, BridgedInstruction inst) {
|
|
||||||
return castToNodeSet(set)->insert(inst.getInst()->asSILNode()) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeSet_eraseInstruction(BridgedNodeSet set, BridgedInstruction inst) {
|
|
||||||
castToNodeSet(set)->erase(inst.getInst()->asSILNode());
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedFunction NodeSet_getFunction(BridgedNodeSet set) {
|
|
||||||
return {castToNodeSet(set)->getFunction()};
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllocRefInstBase_setIsStackAllocatable(BridgedInstruction arb) {
|
|
||||||
arb.getAs<AllocRefInstBase>()->setStackAllocatable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TermInst_replaceBranchTarget(BridgedInstruction term, BridgedBasicBlock from,
|
|
||||||
BridgedBasicBlock to) {
|
|
||||||
term.getAs<TermInst>()->replaceBranchTarget(from.getBlock(), to.getBlock());
|
|
||||||
}
|
|
||||||
|
|
||||||
SubstitutionMap
|
|
||||||
PassContext_getContextSubstitutionMap(BridgedPassContext context,
|
|
||||||
SILType type) {
|
|
||||||
auto *ntd = type.getASTType()->getAnyNominal();
|
|
||||||
auto *pm = castToPassInvocation(context)->getPassManager();
|
|
||||||
auto *m = pm->getModule()->getSwiftModule();
|
|
||||||
|
|
||||||
return type.getASTType()->getContextSubstitutionMap(m, ntd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassContext_beginTransformFunction(BridgedFunction function, BridgedPassContext ctxt) {
|
|
||||||
castToPassInvocation(ctxt)->beginTransformFunction(function.getFunction());
|
|
||||||
}
|
|
||||||
|
|
||||||
void PassContext_endTransformFunction(BridgedPassContext ctxt) {
|
|
||||||
castToPassInvocation(ctxt)->endTransformFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionalBridgedFunction
|
|
||||||
PassContext_firstFunctionInModule(BridgedPassContext context) {
|
|
||||||
SILModule *mod = castToPassInvocation(context)->getPassManager()->getModule();
|
|
||||||
if (mod->getFunctions().empty())
|
|
||||||
return {nullptr};
|
|
||||||
return {&*mod->getFunctions().begin()};
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionalBridgedFunction
|
|
||||||
PassContext_nextFunctionInModule(BridgedFunction function) {
|
|
||||||
auto *f = function.getFunction();
|
|
||||||
auto nextIter = std::next(f->getIterator());
|
|
||||||
if (nextIter == f->getModule().getFunctions().end())
|
|
||||||
return {nullptr};
|
|
||||||
return {&*nextIter};
|
|
||||||
}
|
|
||||||
|
|
||||||
BridgedVTableArray PassContext_getVTables(BridgedPassContext context) {
|
|
||||||
SILModule *mod = castToPassInvocation(context)->getPassManager()->getModule();
|
|
||||||
auto vTables = mod->getVTables();
|
|
||||||
return {(const BridgedVTable *)vTables.data(), (SwiftInt)vTables.size()};
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionalBridgedWitnessTable
|
|
||||||
PassContext_firstWitnessTableInModule(BridgedPassContext context) {
|
|
||||||
SILModule *mod = castToPassInvocation(context)->getPassManager()->getModule();
|
|
||||||
if (mod->getWitnessTables().empty())
|
|
||||||
return {nullptr};
|
|
||||||
return {&*mod->getWitnessTables().begin()};
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionalBridgedWitnessTable
|
|
||||||
PassContext_nextWitnessTableInModule(BridgedWitnessTable table) {
|
|
||||||
auto *t = table.table;
|
|
||||||
auto nextIter = std::next(t->getIterator());
|
|
||||||
if (nextIter == t->getModule().getWitnessTables().end())
|
|
||||||
return {nullptr};
|
|
||||||
return {&*nextIter};
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionalBridgedDefaultWitnessTable
|
|
||||||
PassContext_firstDefaultWitnessTableInModule(BridgedPassContext context) {
|
|
||||||
SILModule *mod = castToPassInvocation(context)->getPassManager()->getModule();
|
|
||||||
if (mod->getDefaultWitnessTables().empty())
|
|
||||||
return {nullptr};
|
|
||||||
return {&*mod->getDefaultWitnessTables().begin()};
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionalBridgedDefaultWitnessTable
|
|
||||||
PassContext_nextDefaultWitnessTableInModule(BridgedDefaultWitnessTable table) {
|
|
||||||
auto *t = table.table;
|
|
||||||
auto nextIter = std::next(t->getIterator());
|
|
||||||
if (nextIter == t->getModule().getDefaultWitnessTables().end())
|
|
||||||
return {nullptr};
|
|
||||||
return {&*nextIter};
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionalBridgedFunction
|
|
||||||
PassContext_loadFunction(BridgedPassContext context, StringRef name) {
|
|
||||||
SILModule *mod = castToPassInvocation(context)->getPassManager()->getModule();
|
|
||||||
SILFunction *f = mod->loadFunction(name, SILModule::LinkingMode::LinkNormal);
|
|
||||||
return {f};
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt SILOptions_enableStackProtection(BridgedPassContext context) {
|
|
||||||
SILModule *mod = castToPassInvocation(context)->getPassManager()->getModule();
|
|
||||||
return mod->getOptions().EnableStackProtection;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwiftInt SILOptions_enableMoveInoutStackProtection(BridgedPassContext context) {
|
|
||||||
SILModule *mod = castToPassInvocation(context)->getPassManager()->getModule();
|
|
||||||
return mod->getOptions().EnableMoveInoutStackProtection;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SILOptions_enableSimplificationFor(BridgedInstruction inst) {
|
|
||||||
// Fast-path check.
|
// Fast-path check.
|
||||||
if (SimplifyInstructionTest.empty() && SILDisablePass.empty())
|
if (SimplifyInstructionTest.empty() && SILDisablePass.empty())
|
||||||
return true;
|
return true;
|
||||||
@@ -1738,8 +1444,3 @@ bool SILOptions_enableSimplificationFor(BridgedInstruction inst) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
BridgedValue SILUndef_get(SILType type, BridgedPassContext context) {
|
|
||||||
SILUndef *undef = SILUndef::get(type, *castToPassInvocation(context)->getFunction());
|
|
||||||
return {undef};
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user