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
|
||||
|
||||
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:
|
||||
return true
|
||||
default:
|
||||
@@ -26,7 +26,7 @@ struct AliasAnalysis {
|
||||
}
|
||||
|
||||
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:
|
||||
return true
|
||||
default:
|
||||
@@ -35,7 +35,7 @@ struct AliasAnalysis {
|
||||
}
|
||||
|
||||
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:
|
||||
return true
|
||||
default:
|
||||
@@ -61,7 +61,7 @@ struct AliasAnalysis {
|
||||
}
|
||||
|
||||
static func register() {
|
||||
AliasAnalysis_register(
|
||||
BridgedAliasAnalysis.registerAnalysis(
|
||||
// getMemEffectsFn
|
||||
{ (bridgedCtxt: BridgedPassContext, bridgedVal: BridgedValue, bridgedInst: BridgedInstruction) -> swift.MemoryBehavior in
|
||||
let context = FunctionPassContext(_bridged: bridgedCtxt)
|
||||
|
||||
@@ -17,7 +17,7 @@ public struct CalleeAnalysis {
|
||||
let bridged: BridgedCalleeAnalysis
|
||||
|
||||
static func register() {
|
||||
CalleeAnalysis_register(
|
||||
BridgedCalleeAnalysis.registerAnalysis(
|
||||
// isDeinitBarrierFn:
|
||||
{ (inst : BridgedInstruction, bca: BridgedCalleeAnalysis) -> Bool in
|
||||
return inst.instruction.isDeinitBarrier(bca.analysis)
|
||||
@@ -33,19 +33,19 @@ public struct CalleeAnalysis {
|
||||
}
|
||||
|
||||
public func getCallees(callee: Value) -> FunctionArray? {
|
||||
let bridgedFuncs = CalleeAnalysis_getCallees(bridged, callee.bridged)
|
||||
if bridgedFuncs.incomplete != 0 {
|
||||
let bridgedFuncs = bridged.getCallees(callee.bridged)
|
||||
if bridgedFuncs.isIncomplete() {
|
||||
return nil
|
||||
}
|
||||
return FunctionArray(bridged: bridgedFuncs)
|
||||
}
|
||||
|
||||
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? {
|
||||
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 {
|
||||
return destructors[0]
|
||||
}
|
||||
@@ -53,8 +53,8 @@ public struct CalleeAnalysis {
|
||||
}
|
||||
|
||||
public func getDestructors(of type: Type) -> FunctionArray? {
|
||||
let bridgedDtors = CalleeAnalysis_getDestructors(bridged, type.bridged, /*isExactType*/ 0)
|
||||
if bridgedDtors.incomplete != 0 {
|
||||
let bridgedDtors = bridged.getDestructors(type.bridged, /*isExactType*/ false)
|
||||
if bridgedDtors.isIncomplete() {
|
||||
return nil
|
||||
}
|
||||
return FunctionArray(bridged: bridgedDtors)
|
||||
@@ -123,13 +123,13 @@ extension Instruction {
|
||||
}
|
||||
|
||||
public struct FunctionArray : RandomAccessCollection, FormattedLikeArray {
|
||||
fileprivate let bridged: BridgedCalleeList
|
||||
fileprivate let bridged: swift.CalleeList
|
||||
|
||||
public var startIndex: Int { 0 }
|
||||
public var endIndex: Int { BridgedFunctionArray_size(bridged) }
|
||||
public var endIndex: Int { Int(bridged.getCount()) }
|
||||
|
||||
public subscript(_ index: Int) -> Function {
|
||||
return BridgedFunctionArray_get(bridged, index).function
|
||||
return BridgedCalleeAnalysis.getCallee(bridged, index).function
|
||||
}
|
||||
}
|
||||
// Bridging utilities
|
||||
|
||||
@@ -17,6 +17,6 @@ public struct DeadEndBlocksAnalysis {
|
||||
let bridged: BridgedDeadEndBlocksAnalysis
|
||||
|
||||
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 {
|
||||
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 {
|
||||
|
||||
@@ -19,7 +19,7 @@ public struct PostDominatorTree {
|
||||
|
||||
extension BasicBlock {
|
||||
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 {
|
||||
|
||||
@@ -38,25 +38,25 @@ struct BasicBlockSet : IntrusiveSet {
|
||||
|
||||
init(_ context: some Context) {
|
||||
self.context = context._bridged
|
||||
self.bridged = PassContext_allocBasicBlockSet(self.context)
|
||||
self.bridged = self.context.allocBasicBlockSet()
|
||||
}
|
||||
|
||||
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.
|
||||
@discardableResult
|
||||
mutating func insert(_ block: BasicBlock) -> Bool {
|
||||
BasicBlockSet_insert(bridged, block.bridged) != 0
|
||||
bridged.insert(block.bridged)
|
||||
}
|
||||
|
||||
mutating func erase(_ block: BasicBlock) {
|
||||
BasicBlockSet_erase(bridged, block.bridged)
|
||||
bridged.erase(block.bridged)
|
||||
}
|
||||
|
||||
var description: String {
|
||||
let function = BasicBlockSet_getFunction(bridged).function
|
||||
let function = bridged.getFunction().function
|
||||
let blockNames = function.blocks.enumerated().filter { contains($0.1) }
|
||||
.map { "bb\($0.0)"}
|
||||
return "{" + blockNames.joined(separator: ", ") + "}"
|
||||
@@ -64,7 +64,7 @@ struct BasicBlockSet : IntrusiveSet {
|
||||
|
||||
/// TODO: once we have move-only types, make this a real deinit.
|
||||
mutating func deinitialize() {
|
||||
PassContext_freeBasicBlockSet(context, bridged)
|
||||
context.freeBasicBlockSet(bridged)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,25 +83,25 @@ struct ValueSet : IntrusiveSet {
|
||||
|
||||
init(_ context: some Context) {
|
||||
self.context = context._bridged
|
||||
self.bridged = PassContext_allocNodeSet(self.context)
|
||||
self.bridged = self.context.allocNodeSet()
|
||||
}
|
||||
|
||||
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.
|
||||
@discardableResult
|
||||
mutating func insert(_ value: Value) -> Bool {
|
||||
NodeSet_insertValue(bridged, value.bridged) != 0
|
||||
bridged.insertValue(value.bridged)
|
||||
}
|
||||
|
||||
mutating func erase(_ value: Value) {
|
||||
NodeSet_eraseValue(bridged, value.bridged)
|
||||
bridged.eraseValue(value.bridged)
|
||||
}
|
||||
|
||||
var description: String {
|
||||
let function = NodeSet_getFunction(bridged).function
|
||||
let function = bridged.getFunction().function
|
||||
var d = "{\n"
|
||||
for block in function.blocks {
|
||||
for arg in block.arguments {
|
||||
@@ -123,7 +123,7 @@ struct ValueSet : IntrusiveSet {
|
||||
|
||||
/// TODO: once we have move-only types, make this a real deinit.
|
||||
mutating func deinitialize() {
|
||||
PassContext_freeNodeSet(context, bridged)
|
||||
context.freeNodeSet(bridged)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,25 +142,25 @@ struct InstructionSet : IntrusiveSet {
|
||||
|
||||
init(_ context: some Context) {
|
||||
self.context = context._bridged
|
||||
self.bridged = PassContext_allocNodeSet(self.context)
|
||||
self.bridged = self.context.allocNodeSet()
|
||||
}
|
||||
|
||||
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.
|
||||
@discardableResult
|
||||
mutating func insert(_ inst: Instruction) -> Bool {
|
||||
NodeSet_insertInstruction(bridged, inst.bridged) != 0
|
||||
bridged.insertInstruction(inst.bridged)
|
||||
}
|
||||
|
||||
mutating func erase(_ inst: Instruction) {
|
||||
NodeSet_eraseInstruction(bridged, inst.bridged)
|
||||
bridged.eraseInstruction(inst.bridged)
|
||||
}
|
||||
|
||||
var description: String {
|
||||
let function = NodeSet_getFunction(bridged).function
|
||||
let function = bridged.getFunction().function
|
||||
var d = "{\n"
|
||||
for inst in function.instructions {
|
||||
if contains(inst) {
|
||||
@@ -173,6 +173,6 @@ struct InstructionSet : IntrusiveSet {
|
||||
|
||||
/// TODO: once we have move-only types, make this a real deinit.
|
||||
mutating func deinitialize() {
|
||||
PassContext_freeNodeSet(context, bridged)
|
||||
context.freeNodeSet(bridged)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,22 +27,22 @@ import SIL
|
||||
struct Stack<Element> : CollectionLikeSequence {
|
||||
|
||||
private let bridgedContext: BridgedPassContext
|
||||
private var firstSlab = BridgedSlab(data: nil)
|
||||
private var lastSlab = BridgedSlab(data: nil)
|
||||
private var firstSlab = BridgedPassContext.Slab(nil)
|
||||
private var lastSlab = BridgedPassContext.Slab(nil)
|
||||
private var endIndex: Int = 0
|
||||
|
||||
private static var slabCapacity: Int {
|
||||
BridgedSlabCapacity / MemoryLayout<Element>.stride
|
||||
BridgedPassContext.Slab.getCapacity() / MemoryLayout<Element>.stride
|
||||
}
|
||||
|
||||
private static func bind(_ slab: BridgedSlab) -> UnsafeMutablePointer<Element> {
|
||||
return slab.data!.bindMemory(to: Element.self, capacity: Stack.slabCapacity)
|
||||
private static func bind(_ slab: BridgedPassContext.Slab) -> UnsafeMutablePointer<Element> {
|
||||
return UnsafeMutableRawPointer(slab.data!).bindMemory(to: Element.self, capacity: Stack.slabCapacity)
|
||||
}
|
||||
|
||||
struct Iterator : IteratorProtocol {
|
||||
var slab: BridgedSlab
|
||||
var slab: BridgedPassContext.Slab
|
||||
var index: Int
|
||||
let lastSlab: BridgedSlab
|
||||
let lastSlab: BridgedPassContext.Slab
|
||||
let endIndex: Int
|
||||
|
||||
mutating func next() -> Element? {
|
||||
@@ -52,7 +52,7 @@ struct Stack<Element> : CollectionLikeSequence {
|
||||
index += 1
|
||||
|
||||
if index >= end && slab.data != lastSlab.data {
|
||||
slab = PassContext_getNextSlab(slab)
|
||||
slab = slab.getNext()
|
||||
index = 0
|
||||
}
|
||||
return elem
|
||||
@@ -77,11 +77,11 @@ struct Stack<Element> : CollectionLikeSequence {
|
||||
|
||||
mutating func push(_ element: Element) {
|
||||
if endIndex >= Stack.slabCapacity {
|
||||
lastSlab = PassContext_allocSlab(bridgedContext, lastSlab)
|
||||
lastSlab = bridgedContext.allocSlab(lastSlab)
|
||||
endIndex = 0
|
||||
} else if firstSlab.data == nil {
|
||||
assert(endIndex == 0)
|
||||
firstSlab = PassContext_allocSlab(bridgedContext, lastSlab)
|
||||
firstSlab = bridgedContext.allocSlab(lastSlab)
|
||||
lastSlab = firstSlab
|
||||
}
|
||||
(Stack.bind(lastSlab) + endIndex).initialize(to: element)
|
||||
@@ -109,12 +109,12 @@ struct Stack<Element> : CollectionLikeSequence {
|
||||
|
||||
if endIndex == 0 {
|
||||
if lastSlab.data == firstSlab.data {
|
||||
_ = PassContext_freeSlab(bridgedContext, lastSlab)
|
||||
_ = bridgedContext.freeSlab(lastSlab)
|
||||
firstSlab.data = nil
|
||||
lastSlab.data = nil
|
||||
endIndex = 0
|
||||
} else {
|
||||
lastSlab = PassContext_freeSlab(bridgedContext, lastSlab)
|
||||
lastSlab = bridgedContext.freeSlab(lastSlab)
|
||||
endIndex = Stack.slabCapacity
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ extension Context {
|
||||
// The calleeAnalysis is not specific to a function and therefore can be provided in
|
||||
// all contexts.
|
||||
var calleeAnalysis: CalleeAnalysis {
|
||||
let bridgeCA = PassContext_getCalleeAnalysis(_bridged)
|
||||
let bridgeCA = _bridged.getCalleeAnalysis()
|
||||
return CalleeAnalysis(bridged: bridgeCA)
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,8 @@ protocol MutatingContext : Context {
|
||||
}
|
||||
|
||||
extension MutatingContext {
|
||||
func notifyInvalidatedStackNesting() { PassContext_notifyInvalidatedStackNesting(_bridged) }
|
||||
var needFixStackNesting: Bool { PassContext_getNeedFixStackNesting(_bridged) }
|
||||
func notifyInvalidatedStackNesting() { _bridged.notifyInvalidatedStackNesting() }
|
||||
var needFixStackNesting: Bool { _bridged.getNeedFixStackNesting() }
|
||||
|
||||
/// Splits the basic block, which contains `inst`, before `inst` and returns the
|
||||
/// new block.
|
||||
@@ -46,7 +46,7 @@ extension MutatingContext {
|
||||
/// instructions _before_ `inst` remain in the original block.
|
||||
func splitBlock(at inst: Instruction) -> BasicBlock {
|
||||
notifyBranchesChanged()
|
||||
return PassContext_splitBlock(inst.bridged).block
|
||||
return _bridged.splitBlock(inst.bridged).block
|
||||
}
|
||||
|
||||
func erase(instruction: Instruction) {
|
||||
@@ -58,7 +58,7 @@ extension MutatingContext {
|
||||
}
|
||||
notifyInstructionsChanged()
|
||||
|
||||
PassContext_eraseInstruction(_bridged, instruction.bridged)
|
||||
_bridged.eraseInstruction(instruction.bridged)
|
||||
}
|
||||
|
||||
func erase(instructionIncludingDebugUses inst: Instruction) {
|
||||
@@ -72,25 +72,25 @@ extension MutatingContext {
|
||||
}
|
||||
|
||||
func tryDeleteDeadClosure(closure: SingleValueInstruction) -> Bool {
|
||||
PassContext_tryDeleteDeadClosure(_bridged, closure.bridged)
|
||||
_bridged.tryDeleteDeadClosure(closure.bridged)
|
||||
}
|
||||
|
||||
func getContextSubstitutionMap(for type: Type) -> SubstitutionMap {
|
||||
SubstitutionMap(PassContext_getContextSubstitutionMap(_bridged, type.bridged))
|
||||
SubstitutionMap(_bridged.getContextSubstitutionMap(type.bridged))
|
||||
}
|
||||
|
||||
// Private utilities
|
||||
|
||||
fileprivate func notifyInstructionsChanged() {
|
||||
PassContext_notifyChanges(_bridged, instructionsChanged)
|
||||
_bridged.asNotificationHandler().notifyChanges(.instructionsChanged)
|
||||
}
|
||||
|
||||
fileprivate func notifyCallsChanged() {
|
||||
PassContext_notifyChanges(_bridged, callsChanged)
|
||||
_bridged.asNotificationHandler().notifyChanges(.callsChanged)
|
||||
}
|
||||
|
||||
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 {
|
||||
let bridgedInst = OptionalBridgedInstruction(inst?.bridged.obj)
|
||||
return PassContext_continueWithNextSubpassRun(_bridged, bridgedInst) != 0
|
||||
return _bridged.continueWithNextSubpassRun(bridgedInst)
|
||||
}
|
||||
|
||||
func createSimplifyContext(preserveDebugInfo: Bool, notifyInstructionChanged: @escaping (Instruction) -> ()) -> SimplifyContext {
|
||||
@@ -111,33 +111,33 @@ struct FunctionPassContext : MutatingContext {
|
||||
}
|
||||
|
||||
var aliasAnalysis: AliasAnalysis {
|
||||
let bridgedAA = PassContext_getAliasAnalysis(_bridged)
|
||||
let bridgedAA = _bridged.getAliasAnalysis()
|
||||
return AliasAnalysis(bridged: bridgedAA)
|
||||
}
|
||||
|
||||
var deadEndBlocks: DeadEndBlocksAnalysis {
|
||||
let bridgeDEA = PassContext_getDeadEndBlocksAnalysis(_bridged)
|
||||
let bridgeDEA = _bridged.getDeadEndBlocksAnalysis()
|
||||
return DeadEndBlocksAnalysis(bridged: bridgeDEA)
|
||||
}
|
||||
|
||||
var dominatorTree: DominatorTree {
|
||||
let bridgedDT = PassContext_getDomTree(_bridged)
|
||||
let bridgedDT = _bridged.getDomTree()
|
||||
return DominatorTree(bridged: bridgedDT)
|
||||
}
|
||||
|
||||
var postDominatorTree: PostDominatorTree {
|
||||
let bridgedPDT = PassContext_getPostDomTree(_bridged)
|
||||
let bridgedPDT = _bridged.getPostDomTree()
|
||||
return PostDominatorTree(bridged: bridgedPDT)
|
||||
}
|
||||
|
||||
func loadFunction(name: StaticString) -> Function? {
|
||||
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) {
|
||||
PassContext_eraseBlock(_bridged, block.bridged)
|
||||
_bridged.eraseBlock(block.bridged)
|
||||
}
|
||||
|
||||
func modifyEffects(in function: Function, _ body: (inout FunctionEffects) -> ()) {
|
||||
@@ -146,7 +146,7 @@ struct FunctionPassContext : MutatingContext {
|
||||
}
|
||||
|
||||
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`.
|
||||
init(before insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
||||
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`.
|
||||
init(before insPnt: Instruction, _ context: some MutatingContext) {
|
||||
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`.
|
||||
init(after insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
||||
if let nextInst = insPnt.next {
|
||||
self.init(insertAt: .before(nextInst), location: location,
|
||||
context.notifyInstructionChanged, context._bridged)
|
||||
context.notifyInstructionChanged, context._bridged.asNotificationHandler())
|
||||
} else {
|
||||
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`.
|
||||
init(atEndOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
||||
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`.
|
||||
init(atBeginOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
||||
let firstInst = block.instructions.first!
|
||||
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
|
||||
@@ -207,7 +207,7 @@ extension Builder {
|
||||
init(atBeginOf block: BasicBlock, _ context: some MutatingContext) {
|
||||
let firstInst = block.instructions.first!
|
||||
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 {
|
||||
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 {
|
||||
func setIsStackAllocatable(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
AllocRefInstBase_setIsStackAllocatable(bridged)
|
||||
bridged.AllocRefInstBase_setIsStackAllocatable()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
@@ -294,7 +294,7 @@ extension RefCountingInst {
|
||||
extension TermInst {
|
||||
func replaceBranchTarget(from fromBlock: BasicBlock, to toBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
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) {
|
||||
PassContext_fixStackNesting(context._bridged, bridged)
|
||||
context._bridged.fixStackNesting(bridged)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ struct ModulePassContext : Context {
|
||||
|
||||
mutating func next() -> Function? {
|
||||
if let f = currentFunction {
|
||||
currentFunction = PassContext_nextFunctionInModule(f.bridged).function
|
||||
currentFunction = BridgedPassContext.getNextFunctionInModule(f.bridged).function
|
||||
return f
|
||||
}
|
||||
return nil
|
||||
@@ -36,14 +36,14 @@ struct ModulePassContext : Context {
|
||||
}
|
||||
|
||||
struct VTableArray : BridgedRandomAccessCollection {
|
||||
fileprivate let bridged: BridgedVTableArray
|
||||
fileprivate let bridged: BridgedPassContext.VTableArray
|
||||
|
||||
var startIndex: Int { return 0 }
|
||||
var endIndex: Int { return bridged.count }
|
||||
|
||||
subscript(_ index: Int) -> VTable {
|
||||
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? {
|
||||
if let t = currentTable {
|
||||
currentTable = PassContext_nextWitnessTableInModule(t.bridged).witnessTable
|
||||
currentTable = BridgedPassContext.getNextWitnessTableInModule(t.bridged).witnessTable
|
||||
return t
|
||||
}
|
||||
return nil
|
||||
@@ -68,7 +68,7 @@ struct ModulePassContext : Context {
|
||||
|
||||
mutating func next() -> DefaultWitnessTable? {
|
||||
if let t = currentTable {
|
||||
currentTable = PassContext_nextDefaultWitnessTableInModule(t.bridged).defaultWitnessTable
|
||||
currentTable = BridgedPassContext.getNextDefaultWitnessTableInModule(t.bridged).defaultWitnessTable
|
||||
return t
|
||||
}
|
||||
return nil
|
||||
@@ -76,19 +76,19 @@ struct ModulePassContext : Context {
|
||||
}
|
||||
|
||||
var functions: FunctionList {
|
||||
FunctionList(first: PassContext_firstFunctionInModule(_bridged).function)
|
||||
FunctionList(first: _bridged.getFirstFunctionInModule().function)
|
||||
}
|
||||
|
||||
var vTables: VTableArray {
|
||||
VTableArray(bridged: PassContext_getVTables(_bridged))
|
||||
VTableArray(bridged: _bridged.getVTables())
|
||||
}
|
||||
|
||||
var witnessTables: WitnessTableList {
|
||||
WitnessTableList(first: PassContext_firstWitnessTableInModule(_bridged).witnessTable)
|
||||
WitnessTableList(first: _bridged.getFirstWitnessTableInModule().witnessTable)
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -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
|
||||
/// calls to `transform`.
|
||||
func transform(function: Function, _ runOnFunction: (FunctionPassContext) -> ()) {
|
||||
PassContext_beginTransformFunction(function.bridged, _bridged)
|
||||
_bridged.beginTransformFunction(function.bridged)
|
||||
runOnFunction(FunctionPassContext(_bridged: _bridged))
|
||||
PassContext_endTransformFunction(_bridged);
|
||||
_bridged.endTransformFunction();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ struct Options {
|
||||
let _bridged: BridgedPassContext
|
||||
|
||||
var enableStackProtection: Bool {
|
||||
SILOptions_enableStackProtection(_bridged) != 0
|
||||
_bridged.enableStackProtection()
|
||||
}
|
||||
|
||||
var enableMoveInoutStackProtection: Bool {
|
||||
SILOptions_enableMoveInoutStackProtection(_bridged) != 0
|
||||
_bridged.enableMoveInoutStackProtection()
|
||||
}
|
||||
|
||||
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 location: Location
|
||||
private let passContext: BridgedPassContext
|
||||
private let notificationHandler: BridgedChangeNotificationHandler
|
||||
private let notifyNewInstruction: (Instruction) -> ()
|
||||
|
||||
private var bridged: BridgedBuilder {
|
||||
@@ -40,12 +40,12 @@ public struct Builder {
|
||||
}
|
||||
|
||||
private func notifyNew<I: Instruction>(_ instruction: I) -> I {
|
||||
PassContext_notifyChanges(passContext, instructionsChanged)
|
||||
notificationHandler.notifyChanges(.instructionsChanged)
|
||||
if instruction is FullApplySite {
|
||||
PassContext_notifyChanges(passContext, callsChanged)
|
||||
notificationHandler.notifyChanges(.callsChanged)
|
||||
}
|
||||
if instruction is TermInst {
|
||||
PassContext_notifyChanges(passContext, branchesChanged)
|
||||
notificationHandler.notifyChanges(.branchesChanged)
|
||||
}
|
||||
notifyNewInstruction(instruction)
|
||||
return instruction
|
||||
@@ -53,11 +53,11 @@ public struct Builder {
|
||||
|
||||
public init(insertAt: InsertionPoint, location: Location,
|
||||
_ notifyNewInstruction: @escaping (Instruction) -> (),
|
||||
_ passContext: BridgedPassContext) {
|
||||
_ notificationHandler: BridgedChangeNotificationHandler) {
|
||||
self.insertAt = insertAt
|
||||
self.location = location;
|
||||
self.notifyNewInstruction = notifyNewInstruction
|
||||
self.passContext = passContext
|
||||
self.notificationHandler = notificationHandler
|
||||
}
|
||||
|
||||
public func createBuiltinBinaryFunction(name: String,
|
||||
|
||||
@@ -40,16 +40,7 @@ struct BridgedBasicBlock;
|
||||
struct BridgedSuccessorArray;
|
||||
struct OptionalBridgedBasicBlock;
|
||||
|
||||
enum ChangeNotificationKind {
|
||||
instructionsChanged,
|
||||
callsChanged,
|
||||
branchesChanged,
|
||||
effectsChanged
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const void * _Nonnull opaqueCtxt;
|
||||
} BridgedPassContext;
|
||||
void registerBridgedClass(llvm::StringRef className, SwiftMetatype metatype);
|
||||
|
||||
struct BridgedValue {
|
||||
SwiftObject obj;
|
||||
@@ -613,6 +604,12 @@ struct BridgedInstruction {
|
||||
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 {
|
||||
if (swift::KeyPathPattern *pattern = getAs<swift::KeyPathInst>()->getPattern()) {
|
||||
return (SwiftInt)pattern->getComponents().size();
|
||||
@@ -1052,17 +1049,24 @@ struct BridgedNominalTypeDecl {
|
||||
swift::NominalTypeDecl * _Nonnull decl;
|
||||
};
|
||||
|
||||
void registerBridgedClass(llvm::StringRef className, SwiftMetatype metatype);
|
||||
// Passmanager and Context
|
||||
|
||||
SwiftInt PassContext_continueWithNextSubpassRun(BridgedPassContext passContext,
|
||||
OptionalBridgedInstruction inst);
|
||||
void PassContext_notifyChanges(BridgedPassContext passContext,
|
||||
enum ChangeNotificationKind changeKind);
|
||||
BridgedBasicBlock PassContext_splitBlock(BridgedInstruction bridgedInst);
|
||||
void PassContext_eraseInstruction(BridgedPassContext passContext,
|
||||
BridgedInstruction inst);
|
||||
void PassContext_eraseBlock(BridgedPassContext passContext,
|
||||
BridgedBasicBlock block);
|
||||
namespace swift {
|
||||
class SwiftPassInvocation;
|
||||
}
|
||||
|
||||
struct BridgedChangeNotificationHandler {
|
||||
swift::SwiftPassInvocation * _Nonnull invocation;
|
||||
|
||||
enum class Kind {
|
||||
instructionsChanged,
|
||||
callsChanged,
|
||||
branchesChanged,
|
||||
effectsChanged
|
||||
};
|
||||
|
||||
void notifyChanges(Kind changeKind) const;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Inline functions
|
||||
@@ -1115,6 +1119,10 @@ BridgedBasicBlock BridgedInstruction::BranchInst_getTargetBlock() const {
|
||||
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 {
|
||||
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; }
|
||||
|
||||
/// Returns true if all callees are known and not external.
|
||||
|
||||
@@ -14,71 +14,400 @@
|
||||
#define SWIFT_SILOPTIMIZER_OPTIMIZERBRIDGING_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
|
||||
|
||||
typedef struct {
|
||||
struct BridgedPassContext;
|
||||
|
||||
struct BridgedAliasAnalysis {
|
||||
swift::AliasAnalysis * _Nonnull aa;
|
||||
|
||||
swift::MemoryBehavior getMemBehavior(BridgedInstruction inst, BridgedValue addr) const {
|
||||
return aa->computeMemoryBehavior(inst.getInst(), addr.getSILValue());
|
||||
}
|
||||
|
||||
typedef swift::MemoryBehavior (* _Nonnull GetMemEffectFn)(
|
||||
BridgedPassContext context, BridgedValue, BridgedInstruction);
|
||||
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);
|
||||
|
||||
static void registerAnalysis(GetMemEffectFn getMemEffectsFn,
|
||||
Escaping2InstFn isObjReleasedFn,
|
||||
Escaping2ValIntFn isAddrVisibleFromObjFn,
|
||||
Escaping2ValFn mayPointToSameAddrFn);
|
||||
};
|
||||
|
||||
struct BridgedCalleeAnalysis {
|
||||
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);
|
||||
|
||||
static void registerAnalysis(IsDeinitBarrierFn isDeinitBarrierFn,
|
||||
GetMemBehvaiorFn getEffectsFn);
|
||||
};
|
||||
|
||||
struct BridgedDeadEndBlocksAnalysis {
|
||||
swift::DeadEndBlocks * _Nonnull deb;
|
||||
|
||||
bool isDeadEnd(BridgedBasicBlock block) const {
|
||||
return deb->isDeadEnd(block.getBlock());
|
||||
}
|
||||
};
|
||||
|
||||
struct BridgedDomTree {
|
||||
swift::DominanceInfo * _Nonnull di;
|
||||
|
||||
bool dominates(BridgedBasicBlock dominating, BridgedBasicBlock dominated) const {
|
||||
return di->dominates(dominating.getBlock(), dominated.getBlock());
|
||||
}
|
||||
};
|
||||
|
||||
struct BridgedBasicBlockSet {
|
||||
swift::BasicBlockSet * _Nonnull set;
|
||||
|
||||
bool contains(BridgedBasicBlock block) const {
|
||||
return set->contains(block.getBlock());
|
||||
}
|
||||
|
||||
bool insert(BridgedBasicBlock block) const {
|
||||
return set->insert(block.getBlock());
|
||||
}
|
||||
|
||||
void erase(BridgedBasicBlock block) const {
|
||||
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;
|
||||
} BridgedFunctionPassCtxt;
|
||||
} ;
|
||||
|
||||
typedef struct {
|
||||
struct BridgedInstructionPassCtxt {
|
||||
BridgedInstruction instruction;
|
||||
BridgedPassContext passContext;
|
||||
} BridgedInstructionPassCtxt;
|
||||
|
||||
typedef struct {
|
||||
const BridgedVTable * _Nullable vTables;
|
||||
SwiftInt count;
|
||||
} BridgedVTableArray;
|
||||
|
||||
typedef struct {
|
||||
const void * _Nonnull aliasAnalysis;
|
||||
} BridgedAliasAnalysis;
|
||||
|
||||
typedef struct {
|
||||
void * _Nullable bca;
|
||||
} BridgedCalleeAnalysis;
|
||||
|
||||
typedef bool (* _Nonnull InstructionIsDeinitBarrierFn)(BridgedInstruction, BridgedCalleeAnalysis bca);
|
||||
typedef swift::MemoryBehavior (* _Nonnull CalleeAnalysisGetMemBehvaiorFn)(
|
||||
BridgedPassContext context, BridgedInstruction apply, bool observeRetains);
|
||||
|
||||
void CalleeAnalysis_register(InstructionIsDeinitBarrierFn isDeinitBarrierFn,
|
||||
CalleeAnalysisGetMemBehvaiorFn getEffectsFn);
|
||||
|
||||
typedef struct {
|
||||
void * _Nullable dea;
|
||||
} BridgedDeadEndBlocksAnalysis;
|
||||
|
||||
typedef struct {
|
||||
void * _Nullable dt;
|
||||
} BridgedDomTree;
|
||||
|
||||
typedef struct {
|
||||
void * _Nullable pdt;
|
||||
} BridgedPostDomTree;
|
||||
|
||||
typedef struct {
|
||||
void * _Nonnull opaquePtr;
|
||||
unsigned char kind;
|
||||
unsigned char incomplete;
|
||||
} BridgedCalleeList;
|
||||
|
||||
typedef struct {
|
||||
void * _Nullable bbs;
|
||||
} BridgedBasicBlockSet;
|
||||
|
||||
typedef struct {
|
||||
void * _Nullable nds;
|
||||
} BridgedNodeSet;
|
||||
|
||||
typedef struct {
|
||||
void * _Nullable data;
|
||||
} BridgedSlab;
|
||||
|
||||
enum {
|
||||
BridgedSlabCapacity = 64 * sizeof(uintptr_t)
|
||||
};
|
||||
|
||||
typedef void (* _Nonnull BridgedModulePassRunFn)(BridgedPassContext);
|
||||
@@ -92,124 +421,6 @@ void SILPassManager_registerFunctionPass(llvm::StringRef name,
|
||||
void SILCombine_registerInstructionPass(llvm::StringRef instClassName,
|
||||
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
|
||||
|
||||
#endif
|
||||
|
||||
@@ -521,10 +521,10 @@ bool AliasAnalysis::typesMayAlias(SILType T1, SILType T2,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Bridging functions.
|
||||
static AliasAnalysisGetMemEffectFn getMemEffectsFunction = nullptr;
|
||||
static AliasAnalysisEscaping2InstFn isObjReleasedFunction = nullptr;
|
||||
static AliasAnalysisEscaping2ValIntFn isAddrVisibleFromObjFunction = nullptr;
|
||||
static AliasAnalysisEscaping2ValFn canReferenceSameFieldFunction = nullptr;
|
||||
static BridgedAliasAnalysis::GetMemEffectFn getMemEffectsFunction = nullptr;
|
||||
static BridgedAliasAnalysis::Escaping2InstFn isObjReleasedFunction = nullptr;
|
||||
static BridgedAliasAnalysis::Escaping2ValIntFn isAddrVisibleFromObjFunction = nullptr;
|
||||
static BridgedAliasAnalysis::Escaping2ValFn canReferenceSameFieldFunction = nullptr;
|
||||
|
||||
/// The main AA entry point. Performs various analyses on V1, V2 in an attempt
|
||||
/// to disambiguate the two values.
|
||||
@@ -701,21 +701,10 @@ SILAnalysis *swift::createAliasAnalysis(SILModule *M) {
|
||||
// Swift Bridging
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
inline AliasAnalysis *castToAliasAnalysis(BridgedAliasAnalysis aa) {
|
||||
return const_cast<AliasAnalysis *>(
|
||||
static_cast<const AliasAnalysis *>(aa.aliasAnalysis));
|
||||
}
|
||||
|
||||
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) {
|
||||
void BridgedAliasAnalysis::registerAnalysis(GetMemEffectFn getMemEffectsFn,
|
||||
Escaping2InstFn isObjReleasedFn,
|
||||
Escaping2ValIntFn isAddrVisibleFromObjFn,
|
||||
Escaping2ValFn canReferenceSameFieldFn) {
|
||||
getMemEffectsFunction = getMemEffectsFn;
|
||||
isObjReleasedFunction = isObjReleasedFn;
|
||||
isAddrVisibleFromObjFunction = isAddrVisibleFromObjFn;
|
||||
|
||||
@@ -336,42 +336,11 @@ void BasicCalleeAnalysis::print(llvm::raw_ostream &os) const {
|
||||
// Swift Bridging
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
BridgedCalleeList CalleeAnalysis_getCallees(BridgedCalleeAnalysis calleeAnalysis,
|
||||
BridgedValue callee) {
|
||||
BasicCalleeAnalysis *bca = static_cast<BasicCalleeAnalysis *>(calleeAnalysis.bca);
|
||||
CalleeList cl = bca->getCalleeListOfValue(callee.getSILValue());
|
||||
return {cl.getOpaquePtr(), cl.getOpaqueKind(), cl.isIncomplete()};
|
||||
}
|
||||
static BridgedCalleeAnalysis::IsDeinitBarrierFn instructionIsDeinitBarrierFunction;
|
||||
static BridgedCalleeAnalysis::GetMemBehvaiorFn getMemBehvaiorFunction = nullptr;
|
||||
|
||||
BridgedCalleeList CalleeAnalysis_getDestructors(BridgedCalleeAnalysis calleeAnalysis,
|
||||
SILType type,
|
||||
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) {
|
||||
void BridgedCalleeAnalysis::registerAnalysis(IsDeinitBarrierFn instructionIsDeinitBarrierFn,
|
||||
GetMemBehvaiorFn getMemBehvaiorFn) {
|
||||
instructionIsDeinitBarrierFunction = instructionIsDeinitBarrierFn;
|
||||
getMemBehvaiorFunction = getMemBehvaiorFn;
|
||||
}
|
||||
|
||||
@@ -56,13 +56,3 @@ void DeadEndBlocksAnalysis::verify(DeadEndBlocks *deBlocks) const {
|
||||
SILAnalysis *swift::createDeadEndBlocksAnalysis(SILModule *) {
|
||||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static_assert(BridgedSlabCapacity == FixedSizeSlab::capacity,
|
||||
"wrong bridged slab capacity");
|
||||
|
||||
FixedSizeSlab *SwiftPassInvocation::allocSlab(FixedSizeSlab *afterSlab) {
|
||||
FixedSizeSlab *slab = passManager->getModule()->allocSlab();
|
||||
if (afterSlab) {
|
||||
@@ -1393,333 +1390,42 @@ void SwiftPassInvocation::endTransformFunction() {
|
||||
// Swift Bridging
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
inline SwiftPassInvocation *castToPassInvocation(BridgedPassContext ctxt) {
|
||||
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);
|
||||
void BridgedChangeNotificationHandler::notifyChanges(Kind changeKind) const {
|
||||
switch (changeKind) {
|
||||
case instructionsChanged:
|
||||
inv->notifyChanges(SILAnalysis::InvalidationKind::Instructions);
|
||||
case Kind::instructionsChanged:
|
||||
invocation->notifyChanges(SILAnalysis::InvalidationKind::Instructions);
|
||||
break;
|
||||
case callsChanged:
|
||||
inv->notifyChanges(SILAnalysis::InvalidationKind::CallsAndInstructions);
|
||||
case Kind::callsChanged:
|
||||
invocation->notifyChanges(SILAnalysis::InvalidationKind::CallsAndInstructions);
|
||||
break;
|
||||
case branchesChanged:
|
||||
inv->notifyChanges(SILAnalysis::InvalidationKind::BranchesAndInstructions);
|
||||
case Kind::branchesChanged:
|
||||
invocation->notifyChanges(SILAnalysis::InvalidationKind::BranchesAndInstructions);
|
||||
break;
|
||||
case effectsChanged:
|
||||
inv->notifyChanges(SILAnalysis::InvalidationKind::Effects);
|
||||
case Kind::effectsChanged:
|
||||
invocation->notifyChanges(SILAnalysis::InvalidationKind::Effects);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BridgedBasicBlock PassContext_splitBlock(BridgedInstruction bridgedInst) {
|
||||
SILInstruction *inst = bridgedInst.getInst();
|
||||
SILBasicBlock *block = inst->getParent();
|
||||
return {block->split(inst->getIterator())};
|
||||
bool BridgedPassContext::tryDeleteDeadClosure(BridgedInstruction closure) const {
|
||||
return ::tryDeleteDeadClosure(closure.getAs<SingleValueInstruction>(), InstModCallbacks());
|
||||
}
|
||||
|
||||
void PassContext_eraseInstruction(BridgedPassContext passContext,
|
||||
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) {
|
||||
void BridgedPassContext::fixStackNesting(BridgedFunction function) const {
|
||||
switch (StackNesting::fixNesting(function.getFunction())) {
|
||||
case StackNesting::Changes::None:
|
||||
break;
|
||||
case StackNesting::Changes::Instructions:
|
||||
PassContext_notifyChanges(passContext, instructionsChanged);
|
||||
invocation->notifyChanges(SILAnalysis::InvalidationKind::Instructions);
|
||||
break;
|
||||
case StackNesting::Changes::CFG:
|
||||
PassContext_notifyChanges(passContext, branchesChanged);
|
||||
invocation->notifyChanges(SILAnalysis::InvalidationKind::BranchesAndInstructions);
|
||||
break;
|
||||
}
|
||||
castToPassInvocation(passContext)->setNeedFixStackNesting(false);
|
||||
invocation->setNeedFixStackNesting(false);
|
||||
}
|
||||
|
||||
BridgedAliasAnalysis PassContext_getAliasAnalysis(BridgedPassContext context) {
|
||||
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) {
|
||||
bool BridgedPassContext::enableSimplificationFor(BridgedInstruction inst) const {
|
||||
// Fast-path check.
|
||||
if (SimplifyInstructionTest.empty() && SILDisablePass.empty())
|
||||
return true;
|
||||
@@ -1738,8 +1444,3 @@ bool SILOptions_enableSimplificationFor(BridgedInstruction inst) {
|
||||
}
|
||||
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