mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SwiftCompilerSources: move SIL-related Context APIs from Optimizer to the SIL module
This commit is contained in:
@@ -102,7 +102,7 @@ private func tryConvertBoxesToStack(in function: Function, _ context: FunctionPa
|
||||
hoistMarkUnresolvedInsts(stackAddress: stack, checkKind: .consumableAndAssignable, context)
|
||||
}
|
||||
if !promotableBoxes.isEmpty {
|
||||
function.fixStackNesting(context)
|
||||
context.fixStackNesting(in: function)
|
||||
}
|
||||
|
||||
return functionsToSpecialize
|
||||
|
||||
@@ -158,7 +158,7 @@ let autodiffClosureSpecialization = FunctionPass(name: "autodiff-closure-special
|
||||
}
|
||||
|
||||
if context.needFixStackNesting {
|
||||
function.fixStackNesting(context)
|
||||
context.fixStackNesting(in: function)
|
||||
}
|
||||
|
||||
remainingSpecializationRounds -= 1
|
||||
@@ -836,7 +836,7 @@ private extension SpecializationCloner {
|
||||
}
|
||||
|
||||
if (self.context.needFixStackNesting) {
|
||||
self.cloned.fixStackNesting(self.context)
|
||||
self.context.fixStackNesting(in: self.cloned)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ let computeEscapeEffects = FunctionPass(name: "compute-escape-effects") {
|
||||
return
|
||||
}
|
||||
|
||||
context.modifyEffects(in: function) { (effects: inout FunctionEffects) in
|
||||
function.modifyEffects(context) { (effects: inout FunctionEffects) in
|
||||
effects.escapeEffects.arguments = newEffects
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ let computeSideEffects = FunctionPass(name: "compute-side-effects") {
|
||||
}
|
||||
|
||||
// Finally replace the function's side effects.
|
||||
context.modifyEffects(in: function) { (effects: inout FunctionEffects) in
|
||||
function.modifyEffects(context) { (effects: inout FunctionEffects) in
|
||||
let globalEffects = function.isProgramTerminationPoint ?
|
||||
collectedEffects.globalEffects.forProgramTerminationPoints
|
||||
: collectedEffects.globalEffects
|
||||
|
||||
@@ -110,7 +110,7 @@ func runSimplification(on function: Function, _ context: FunctionPassContext,
|
||||
} while !worklist.isEmpty
|
||||
|
||||
if context.needFixStackNesting {
|
||||
function.fixStackNesting(context)
|
||||
context.fixStackNesting(in: function)
|
||||
}
|
||||
|
||||
return changed
|
||||
|
||||
@@ -57,7 +57,7 @@ let stackPromotion = FunctionPass(name: "stack-promotion") {
|
||||
}
|
||||
if needFixStackNesting {
|
||||
// Make sure that all stack allocating instructions are nested correctly.
|
||||
function.fixStackNesting(context)
|
||||
context.fixStackNesting(in: function)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ extension BuiltinInst : OnoneSimplifiable, SILCombineSimplifiable {
|
||||
case .Xor:
|
||||
simplifyNegation(context)
|
||||
default:
|
||||
if let literal = constantFold(context) {
|
||||
if let literal = context.constantFold(builtin: self) {
|
||||
uses.replaceAll(with: literal, context)
|
||||
}
|
||||
}
|
||||
@@ -240,7 +240,7 @@ private extension BuiltinInst {
|
||||
if constantFoldStringNullPointerCheck(isEqual: isEqual, context) {
|
||||
return
|
||||
}
|
||||
if let literal = constantFold(context) {
|
||||
if let literal = context.constantFold(builtin: self) {
|
||||
uses.replaceAll(with: literal, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ private struct StackProtectionOptimization {
|
||||
process(instruction: inst, in: function, mustFixStackNesting: &mustFixStackNesting, context)
|
||||
}
|
||||
if mustFixStackNesting {
|
||||
function.fixStackNesting(context)
|
||||
context.fixStackNesting(in: function)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -193,15 +193,6 @@ struct FunctionPassContext : MutatingContext {
|
||||
}
|
||||
}
|
||||
|
||||
func modifyEffects(in function: Function, _ body: (inout FunctionEffects) -> ()) {
|
||||
notifyEffectsChanged()
|
||||
function._modifyEffects(body)
|
||||
}
|
||||
|
||||
fileprivate func notifyEffectsChanged() {
|
||||
_bridged.notifyChanges(.Effects)
|
||||
}
|
||||
|
||||
func eliminateDeadAllocations(in function: Function) -> Bool {
|
||||
if bridgedPassContext.eliminateDeadAllocations(function.bridged) {
|
||||
notifyInstructionsChanged()
|
||||
@@ -289,14 +280,24 @@ struct FunctionPassContext : MutatingContext {
|
||||
notifyInstructionsChanged()
|
||||
}
|
||||
}
|
||||
|
||||
func fixStackNesting(in function: Function) {
|
||||
bridgedPassContext.fixStackNesting(function.bridged)
|
||||
}
|
||||
}
|
||||
|
||||
struct SimplifyContext : MutatingContext {
|
||||
let _bridged: BridgedContext
|
||||
let notifyInstructionChanged: (Instruction) -> ()
|
||||
let preserveDebugInfo: Bool
|
||||
|
||||
func constantFold(builtin: BuiltinInst) -> Value? {
|
||||
bridgedPassContext.constantFoldBuiltin(builtin.bridged).value
|
||||
}
|
||||
}
|
||||
|
||||
// Those Type APIs get information from IRGenModule, so they are formally not part of SIL and
|
||||
// therefore need to be defined here, in the Optimizer module.
|
||||
extension Type {
|
||||
func getStaticSize(context: SimplifyContext) -> Int? {
|
||||
let v = context.bridgedPassContext.getStaticSize(self.bridged)
|
||||
@@ -313,372 +314,3 @@ extension Type {
|
||||
return v == -1 ? nil : v
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Builder initialization
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
private extension Instruction {
|
||||
/// Returns self, unless self is a meta instruction, in which case the next
|
||||
/// non-meta instruction is returned. Returns nil if there are no non-meta
|
||||
/// instructions in the basic block.
|
||||
var nextNonMetaInstruction: Instruction? {
|
||||
for inst in InstructionList(first: self) where !(inst is MetaInstruction) {
|
||||
return inst
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
extension Builder {
|
||||
/// Creates a builder which inserts _before_ `insPnt`, using a custom `location`.
|
||||
init(before insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: insPnt.parentFunction)
|
||||
self.init(insertAt: .before(insPnt), location: location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts before `insPnt`, using `insPnt`'s next
|
||||
/// non-meta instruction's location.
|
||||
/// This function should be used when moving code to an unknown insert point,
|
||||
/// when we want to inherit the location of the closest non-meta instruction.
|
||||
/// For replacing an existing meta instruction with another, use
|
||||
/// ``Builder.init(replacing:_:)``.
|
||||
init(before insPnt: Instruction, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: insPnt.parentFunction)
|
||||
self.init(insertAt: .before(insPnt), location: insPnt.location,
|
||||
context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts _before_ `insPnt`, using the exact location of `insPnt`,
|
||||
/// for the purpose of replacing that meta instruction with an equivalent instruction.
|
||||
/// This function does not delete `insPnt`.
|
||||
init(replacing insPnt: MetaInstruction, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: insPnt.parentFunction)
|
||||
self.init(insertAt: .before(insPnt), location: insPnt.location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts _after_ `insPnt`, using a custom `location`.
|
||||
///
|
||||
/// TODO: this is usually incorrect for terminator instructions. Instead use
|
||||
/// `Builder.insert(after:location:_:insertFunc)` from OptUtils.swift. Rename this to afterNonTerminator.
|
||||
init(after insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: insPnt.parentFunction)
|
||||
guard let nextInst = insPnt.next else {
|
||||
fatalError("cannot insert an instruction after a block terminator.")
|
||||
}
|
||||
self.init(insertAt: .before(nextInst), location: location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts _after_ `insPnt`, using `insPnt`'s next
|
||||
/// non-meta instruction's location.
|
||||
///
|
||||
/// TODO: this is incorrect for terminator instructions. Instead use `Builder.insert(after:location:_:insertFunc)`
|
||||
/// from OptUtils.swift. Rename this to afterNonTerminator.
|
||||
init(after insPnt: Instruction, _ context: some MutatingContext) {
|
||||
self.init(after: insPnt, location: insPnt.location, context)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts at the end of `block`, using a custom `location`.
|
||||
init(atEndOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: block.parentFunction)
|
||||
self.init(insertAt: .atEndOf(block), location: location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts at the begin of `block`, using a custom `location`.
|
||||
init(atBeginOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: block.parentFunction)
|
||||
let firstInst = block.instructions.first!
|
||||
self.init(insertAt: .before(firstInst), location: location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts at the begin of `block`, using the location of the first
|
||||
/// non-meta instruction of `block`.
|
||||
init(atBeginOf block: BasicBlock, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: block.parentFunction)
|
||||
let firstInst = block.instructions.first!
|
||||
self.init(insertAt: .before(firstInst),
|
||||
location: firstInst.location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts instructions into an empty function, using the location of the function itself.
|
||||
init(atStartOf function: Function, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: function)
|
||||
self.init(insertAt: .atStartOf(function), location: function.location,
|
||||
context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
init(staticInitializerOf global: GlobalVariable, _ context: some MutatingContext) {
|
||||
self.init(insertAt: .staticInitializer(global),
|
||||
location: Location.artificialUnreachableLocation, { _ in }, context._bridged)
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Modifying the SIL
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
extension Undef {
|
||||
static func get(type: Type, _ context: some MutatingContext) -> Undef {
|
||||
context._bridged.getSILUndef(type.bridged).value as! Undef
|
||||
}
|
||||
}
|
||||
|
||||
extension BasicBlock {
|
||||
func addArgument(type: Type, ownership: Ownership, _ context: some MutatingContext) -> Argument {
|
||||
context.notifyInstructionsChanged()
|
||||
return bridged.addBlockArgument(type.bridged, ownership._bridged).argument
|
||||
}
|
||||
|
||||
func addFunctionArgument(type: Type, _ context: some MutatingContext) -> FunctionArgument {
|
||||
context.notifyInstructionsChanged()
|
||||
return bridged.addFunctionArgument(type.bridged).argument as! FunctionArgument
|
||||
}
|
||||
|
||||
func insertFunctionArgument(atPosition: Int, type: Type, ownership: Ownership, decl: ValueDecl? = nil,
|
||||
_ context: some MutatingContext) -> FunctionArgument
|
||||
{
|
||||
context.notifyInstructionsChanged()
|
||||
return bridged.insertFunctionArgument(atPosition, type.bridged, ownership._bridged,
|
||||
(decl as Decl?).bridged).argument as! FunctionArgument
|
||||
}
|
||||
|
||||
func eraseArgument(at index: Int, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.eraseArgument(index)
|
||||
}
|
||||
|
||||
func moveAllInstructions(toBeginOf otherBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
context.notifyBranchesChanged()
|
||||
bridged.moveAllInstructionsToBegin(otherBlock.bridged)
|
||||
}
|
||||
|
||||
func moveAllInstructions(toEndOf otherBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
context.notifyBranchesChanged()
|
||||
bridged.moveAllInstructionsToEnd(otherBlock.bridged)
|
||||
}
|
||||
|
||||
func eraseAllArguments(_ context: some MutatingContext) {
|
||||
// Arguments are stored in an array. We need to erase in reverse order to avoid quadratic complexity.
|
||||
for argIdx in (0 ..< arguments.count).reversed() {
|
||||
eraseArgument(at: argIdx, context)
|
||||
}
|
||||
}
|
||||
|
||||
func moveAllArguments(to otherBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
bridged.moveArgumentsTo(otherBlock.bridged)
|
||||
}
|
||||
}
|
||||
|
||||
extension Argument {
|
||||
func set(reborrow: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.setReborrow(reborrow)
|
||||
}
|
||||
}
|
||||
|
||||
extension FunctionArgument {
|
||||
/// Copies the following flags from `arg`:
|
||||
/// 1. noImplicitCopy
|
||||
/// 2. lifetimeAnnotation
|
||||
/// 3. closureCapture
|
||||
/// 4. parameterPack
|
||||
func copyFlags(from arg: FunctionArgument, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.copyFlags(arg.bridged)
|
||||
}
|
||||
}
|
||||
|
||||
extension AllocRefInstBase {
|
||||
func setIsStackAllocatable(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.AllocRefInstBase_setIsStackAllocatable()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension Sequence where Element == Operand {
|
||||
func replaceAll(with replacement: Value, _ context: some MutatingContext) {
|
||||
for use in self {
|
||||
use.set(to: replacement, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Operand {
|
||||
func set(to value: Value, _ context: some MutatingContext) {
|
||||
instruction.setOperand(at: index, to: value, context)
|
||||
}
|
||||
|
||||
func changeOwnership(from: Ownership, to: Ownership, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.changeOwnership(from._bridged, to._bridged)
|
||||
context.notifyInstructionChanged(instruction)
|
||||
}
|
||||
}
|
||||
|
||||
extension Instruction {
|
||||
func setOperand(at index : Int, to value: Value, _ context: some MutatingContext) {
|
||||
if let apply = self as? FullApplySite, apply.isCallee(operand: operands[index]) {
|
||||
context.notifyCallsChanged()
|
||||
}
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.setOperand(index, value.bridged)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
|
||||
func move(before otherInstruction: Instruction, _ context: some MutatingContext) {
|
||||
BridgedContext.moveInstructionBefore(bridged, otherInstruction.bridged)
|
||||
context.notifyInstructionsChanged()
|
||||
}
|
||||
}
|
||||
|
||||
extension BuiltinInst {
|
||||
func constantFold(_ context: SimplifyContext) -> Value? {
|
||||
context.bridgedPassContext.constantFoldBuiltin(bridged).value
|
||||
}
|
||||
}
|
||||
|
||||
extension RefCountingInst {
|
||||
func setAtomicity(isAtomic: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.RefCountingInst_setIsAtomic(isAtomic)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension AllocRefInst {
|
||||
func setIsBare(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.AllocRefInst_setIsBare()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension RefElementAddrInst {
|
||||
func set(isImmutable: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.RefElementAddrInst_setImmutable(isImmutable)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension GlobalAddrInst {
|
||||
func clearToken(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.GlobalAddrInst_clearToken()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension GlobalValueInst {
|
||||
func setIsBare(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.GlobalValueInst_setIsBare()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension LoadInst {
|
||||
func set(ownership: LoadInst.LoadOwnership, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.LoadInst_setOwnership(ownership.rawValue)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension PointerToAddressInst {
|
||||
func set(alignment: Int?, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.PointerToAddressInst_setAlignment(UInt64(alignment ?? 0))
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension CopyAddrInst {
|
||||
func set(isTakeOfSource: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.CopyAddrInst_setIsTakeOfSrc(isTakeOfSource)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
|
||||
func set(isInitializationOfDestination: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.CopyAddrInst_setIsInitializationOfDest(isInitializationOfDestination)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension MarkDependenceInstruction {
|
||||
func resolveToNonEscaping(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.MarkDependenceInstruction_resolveToNonEscaping()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
|
||||
func settleToEscaping(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.MarkDependenceInstruction_settleToEscaping()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension BeginAccessInst {
|
||||
func set(accessKind: BeginAccessInst.AccessKind, context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.BeginAccess_setAccessKind(accessKind.rawValue)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
extension TermInst {
|
||||
func replaceBranchTarget(from fromBlock: BasicBlock, to toBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
context.notifyBranchesChanged()
|
||||
bridged.TermInst_replaceBranchTarget(fromBlock.bridged, toBlock.bridged)
|
||||
}
|
||||
}
|
||||
|
||||
extension ForwardingInstruction {
|
||||
func setForwardingOwnership(to ownership: Ownership, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.ForwardingInst_setForwardingOwnership(ownership._bridged)
|
||||
}
|
||||
}
|
||||
|
||||
extension Function {
|
||||
func set(needStackProtection: Bool, _ context: FunctionPassContext) {
|
||||
context.notifyEffectsChanged()
|
||||
bridged.setNeedStackProtection(needStackProtection)
|
||||
}
|
||||
|
||||
func set(thunkKind: ThunkKind, _ context: FunctionPassContext) {
|
||||
context.notifyEffectsChanged()
|
||||
switch thunkKind {
|
||||
case .noThunk: bridged.setThunk(.IsNotThunk)
|
||||
case .thunk: bridged.setThunk(.IsThunk)
|
||||
case .reabstractionThunk: bridged.setThunk(.IsReabstractionThunk)
|
||||
case .signatureOptimizedThunk: bridged.setThunk(.IsSignatureOptimizedThunk)
|
||||
}
|
||||
}
|
||||
|
||||
func set(isPerformanceConstraint: Bool, _ context: FunctionPassContext) {
|
||||
context.notifyEffectsChanged()
|
||||
bridged.setIsPerformanceConstraint(isPerformanceConstraint)
|
||||
}
|
||||
|
||||
func fixStackNesting(_ context: FunctionPassContext) {
|
||||
context.bridgedPassContext.fixStackNesting(bridged)
|
||||
}
|
||||
|
||||
func appendNewBlock(_ context: FunctionPassContext) -> BasicBlock {
|
||||
context.notifyBranchesChanged()
|
||||
return context._bridged.appendBlock(bridged).block
|
||||
}
|
||||
}
|
||||
|
||||
extension DeclRef {
|
||||
func calleesAreStaticallyKnowable(_ context: some Context) -> Bool {
|
||||
context._bridged.calleesAreStaticallyKnowable(bridged)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,24 +341,6 @@ extension Value {
|
||||
}
|
||||
}
|
||||
|
||||
extension SingleValueInstruction {
|
||||
/// Replaces all uses with `replacement` and then erases the instruction.
|
||||
func replace(with replacement: Value, _ context: some MutatingContext) {
|
||||
uses.replaceAll(with: replacement, context)
|
||||
context.erase(instruction: self)
|
||||
}
|
||||
}
|
||||
|
||||
extension MultipleValueInstruction {
|
||||
/// Replaces all uses with the result of `replacement` and then erases the instruction.
|
||||
func replace(with replacement: MultipleValueInstruction, _ context: some MutatingContext) {
|
||||
for (origResult, newResult) in zip(self.results, replacement.results) {
|
||||
origResult.uses.replaceAll(with: newResult, context)
|
||||
}
|
||||
context.erase(instruction: self)
|
||||
}
|
||||
}
|
||||
|
||||
extension Instruction {
|
||||
var isTriviallyDead: Bool {
|
||||
if results.contains(where: { !$0.uses.isEmpty }) {
|
||||
|
||||
@@ -32,6 +32,11 @@ public class Argument : Value, Hashable {
|
||||
|
||||
public var isReborrow: Bool { bridged.isReborrow() }
|
||||
|
||||
public func set(reborrow: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.setReborrow(reborrow)
|
||||
}
|
||||
|
||||
public var isLexical: Bool { false }
|
||||
|
||||
public var decl: ValueDecl? { bridged.getDecl().getAs(ValueDecl.self) }
|
||||
@@ -83,6 +88,16 @@ final public class FunctionArgument : Argument {
|
||||
public var resultDependence: LifetimeDependenceConvention? {
|
||||
parentFunction.argumentConventions[resultDependsOn: index]
|
||||
}
|
||||
|
||||
/// Copies the following flags from `arg`:
|
||||
/// 1. noImplicitCopy
|
||||
/// 2. lifetimeAnnotation
|
||||
/// 3. closureCapture
|
||||
/// 4. parameterPack
|
||||
public func copyFlags(from arg: FunctionArgument, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.copyFlags(arg.bridged)
|
||||
}
|
||||
}
|
||||
|
||||
public struct Phi {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Basic
|
||||
import AST
|
||||
import SILBridging
|
||||
|
||||
@_semantics("arc.immortal")
|
||||
@@ -25,8 +25,69 @@ final public class BasicBlock : CustomStringConvertible, HasShortDescription, Ha
|
||||
}
|
||||
public var shortDescription: String { name }
|
||||
|
||||
/// The index of the basic block in its function.
|
||||
/// This has O(n) complexity. Only use it for debugging
|
||||
public var index: Int {
|
||||
for (idx, block) in parentFunction.blocks.enumerated() {
|
||||
if block == self { return idx }
|
||||
}
|
||||
fatalError()
|
||||
}
|
||||
|
||||
public var name: String { "bb\(index)" }
|
||||
|
||||
public static func == (lhs: BasicBlock, rhs: BasicBlock) -> Bool { lhs === rhs }
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(ObjectIdentifier(self))
|
||||
}
|
||||
|
||||
public var bridged: BridgedBasicBlock { BridgedBasicBlock(SwiftObject(self)) }
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Arguments
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
public var arguments: ArgumentArray { ArgumentArray(block: self) }
|
||||
|
||||
public func addArgument(type: Type, ownership: Ownership, _ context: some MutatingContext) -> Argument {
|
||||
context.notifyInstructionsChanged()
|
||||
return bridged.addBlockArgument(type.bridged, ownership._bridged).argument
|
||||
}
|
||||
|
||||
public func addFunctionArgument(type: Type, _ context: some MutatingContext) -> FunctionArgument {
|
||||
context.notifyInstructionsChanged()
|
||||
return bridged.addFunctionArgument(type.bridged).argument as! FunctionArgument
|
||||
}
|
||||
|
||||
public func insertFunctionArgument(atPosition: Int, type: Type, ownership: Ownership, decl: ValueDecl? = nil,
|
||||
_ context: some MutatingContext) -> FunctionArgument
|
||||
{
|
||||
context.notifyInstructionsChanged()
|
||||
return bridged.insertFunctionArgument(atPosition, type.bridged, ownership._bridged,
|
||||
(decl as Decl?).bridged).argument as! FunctionArgument
|
||||
}
|
||||
|
||||
public func eraseArgument(at index: Int, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.eraseArgument(index)
|
||||
}
|
||||
|
||||
public func eraseAllArguments(_ context: some MutatingContext) {
|
||||
// Arguments are stored in an array. We need to erase in reverse order to avoid quadratic complexity.
|
||||
for argIdx in (0 ..< arguments.count).reversed() {
|
||||
eraseArgument(at: argIdx, context)
|
||||
}
|
||||
}
|
||||
|
||||
public func moveAllArguments(to otherBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
bridged.moveArgumentsTo(otherBlock.bridged)
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
public var instructions: InstructionList {
|
||||
InstructionList(first: bridged.getFirstInst().instruction)
|
||||
}
|
||||
@@ -35,6 +96,22 @@ final public class BasicBlock : CustomStringConvertible, HasShortDescription, Ha
|
||||
bridged.getLastInst().instruction as! TermInst
|
||||
}
|
||||
|
||||
public func moveAllInstructions(toBeginOf otherBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
context.notifyBranchesChanged()
|
||||
bridged.moveAllInstructionsToBegin(otherBlock.bridged)
|
||||
}
|
||||
|
||||
public func moveAllInstructions(toEndOf otherBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
context.notifyBranchesChanged()
|
||||
bridged.moveAllInstructionsToEnd(otherBlock.bridged)
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// predecessors and successors
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
public var successors: SuccessorArray { terminator.successors }
|
||||
|
||||
public var predecessors: PredecessorList {
|
||||
@@ -76,25 +153,6 @@ final public class BasicBlock : CustomStringConvertible, HasShortDescription, Ha
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/// The index of the basic block in its function.
|
||||
/// This has O(n) complexity. Only use it for debugging
|
||||
public var index: Int {
|
||||
for (idx, block) in parentFunction.blocks.enumerated() {
|
||||
if block == self { return idx }
|
||||
}
|
||||
fatalError()
|
||||
}
|
||||
|
||||
public var name: String { "bb\(index)" }
|
||||
|
||||
public static func == (lhs: BasicBlock, rhs: BasicBlock) -> Bool { lhs === rhs }
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(ObjectIdentifier(self))
|
||||
}
|
||||
|
||||
public var bridged: BridgedBasicBlock { BridgedBasicBlock(SwiftObject(self)) }
|
||||
}
|
||||
|
||||
/// The list of instructions in a BasicBlock.
|
||||
|
||||
@@ -29,6 +29,87 @@ public struct Builder {
|
||||
private let notificationHandler: BridgedContext
|
||||
private let notifyNewInstruction: (Instruction) -> ()
|
||||
|
||||
/// Creates a builder which inserts _before_ `insPnt`, using a custom `location`.
|
||||
public init(before insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: insPnt.parentFunction)
|
||||
self.init(insertAt: .before(insPnt), location: location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts before `insPnt`, using `insPnt`'s next
|
||||
/// non-meta instruction's location.
|
||||
/// This function should be used when moving code to an unknown insert point,
|
||||
/// when we want to inherit the location of the closest non-meta instruction.
|
||||
/// For replacing an existing meta instruction with another, use
|
||||
/// ``Builder.init(replacing:_:)``.
|
||||
public init(before insPnt: Instruction, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: insPnt.parentFunction)
|
||||
self.init(insertAt: .before(insPnt), location: insPnt.location,
|
||||
context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts _before_ `insPnt`, using the exact location of `insPnt`,
|
||||
/// for the purpose of replacing that meta instruction with an equivalent instruction.
|
||||
/// This function does not delete `insPnt`.
|
||||
public init(replacing insPnt: MetaInstruction, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: insPnt.parentFunction)
|
||||
self.init(insertAt: .before(insPnt), location: insPnt.location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts _after_ `insPnt`, using a custom `location`.
|
||||
///
|
||||
/// TODO: this is usually incorrect for terminator instructions. Instead use
|
||||
/// `Builder.insert(after:location:_:insertFunc)` from OptUtils.swift. Rename this to afterNonTerminator.
|
||||
public init(after insPnt: Instruction, location: Location, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: insPnt.parentFunction)
|
||||
guard let nextInst = insPnt.next else {
|
||||
fatalError("cannot insert an instruction after a block terminator.")
|
||||
}
|
||||
self.init(insertAt: .before(nextInst), location: location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts _after_ `insPnt`, using `insPnt`'s next
|
||||
/// non-meta instruction's location.
|
||||
///
|
||||
/// TODO: this is incorrect for terminator instructions. Instead use `Builder.insert(after:location:_:insertFunc)`
|
||||
/// from OptUtils.swift. Rename this to afterNonTerminator.
|
||||
public init(after insPnt: Instruction, _ context: some MutatingContext) {
|
||||
self.init(after: insPnt, location: insPnt.location, context)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts at the end of `block`, using a custom `location`.
|
||||
public init(atEndOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: block.parentFunction)
|
||||
self.init(insertAt: .atEndOf(block), location: location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts at the begin of `block`, using a custom `location`.
|
||||
public init(atBeginOf block: BasicBlock, location: Location, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: block.parentFunction)
|
||||
let firstInst = block.instructions.first!
|
||||
self.init(insertAt: .before(firstInst), location: location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts at the begin of `block`, using the location of the first
|
||||
/// non-meta instruction of `block`.
|
||||
public init(atBeginOf block: BasicBlock, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: block.parentFunction)
|
||||
let firstInst = block.instructions.first!
|
||||
self.init(insertAt: .before(firstInst),
|
||||
location: firstInst.location, context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
/// Creates a builder which inserts instructions into an empty function, using the location of the function itself.
|
||||
public init(atStartOf function: Function, _ context: some MutatingContext) {
|
||||
context.verifyIsTransforming(function: function)
|
||||
self.init(insertAt: .atStartOf(function), location: function.location,
|
||||
context.notifyInstructionChanged, context._bridged)
|
||||
}
|
||||
|
||||
public init(staticInitializerOf global: GlobalVariable, _ context: some MutatingContext) {
|
||||
self.init(insertAt: .staticInitializer(global),
|
||||
location: Location.artificialUnreachableLocation, { _ in }, context._bridged)
|
||||
}
|
||||
|
||||
/// Return 'nil' when inserting at the start of a function or in a global initializer.
|
||||
public var insertionBlock: BasicBlock? {
|
||||
switch insertionPoint {
|
||||
@@ -70,7 +151,7 @@ public struct Builder {
|
||||
return instruction
|
||||
}
|
||||
|
||||
public init(insertAt: InsertionPoint, location: Location,
|
||||
private init(insertAt: InsertionPoint, location: Location,
|
||||
_ notifyNewInstruction: @escaping (Instruction) -> (),
|
||||
_ notificationHandler: BridgedContext) {
|
||||
self.insertionPoint = insertAt
|
||||
|
||||
@@ -110,6 +110,10 @@ extension MutatingContext {
|
||||
_bridged.notifyChanges(.Branches)
|
||||
}
|
||||
|
||||
public func notifyEffectsChanged() {
|
||||
_bridged.notifyChanges(.Effects)
|
||||
}
|
||||
|
||||
public func createGlobalVariable(name: String, type: Type, linkage: Linkage, isLet: Bool) -> GlobalVariable {
|
||||
let gv = name._withBridgedStringRef {
|
||||
_bridged.createGlobalVariable($0, type.bridged, linkage.bridged, isLet)
|
||||
|
||||
@@ -30,6 +30,12 @@ public struct DeclRef: CustomStringConvertible, NoReflectionChildren {
|
||||
public static func ==(lhs: DeclRef, rhs: DeclRef) -> Bool {
|
||||
lhs.bridged.isEqualTo(rhs.bridged)
|
||||
}
|
||||
|
||||
/// Do we have enough information to determine all callees that could
|
||||
/// be reached by calling the function represented by Decl?
|
||||
public func calleesAreStaticallyKnowable(_ context: some Context) -> Bool {
|
||||
context._bridged.calleesAreStaticallyKnowable(bridged)
|
||||
}
|
||||
}
|
||||
|
||||
extension DeclRef: DiagnosticArgument {
|
||||
|
||||
@@ -53,7 +53,12 @@ extension ForwardingInstruction {
|
||||
public var forwardingOwnership: Ownership {
|
||||
Ownership(bridged: bridged.ForwardingInst_forwardingOwnership())
|
||||
}
|
||||
|
||||
|
||||
public func setForwardingOwnership(to ownership: Ownership, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.ForwardingInst_setForwardingOwnership(ownership._bridged)
|
||||
}
|
||||
|
||||
/// A forwarding instruction preserves reference counts if it has a dynamically non-trivial result in which all references are forwarded from the operand.
|
||||
///
|
||||
/// A cast can only forward guaranteed values if it preserves reference counts. Such casts cannot release any references within their operand's value and cannot retain any references owned by their result.
|
||||
|
||||
@@ -94,6 +94,11 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
|
||||
|
||||
public var entryBlock: BasicBlock { blocks.first! }
|
||||
|
||||
public func appendNewBlock(_ context: some MutatingContext) -> BasicBlock {
|
||||
context.notifyBranchesChanged()
|
||||
return context._bridged.appendBlock(bridged).block
|
||||
}
|
||||
|
||||
public var arguments: LazyMapSequence<ArgumentArray, FunctionArgument> {
|
||||
entryBlock.arguments.lazy.map { $0 as! FunctionArgument }
|
||||
}
|
||||
@@ -242,6 +247,15 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
public func set(thunkKind: ThunkKind, _ context: some MutatingContext) {
|
||||
context.notifyEffectsChanged()
|
||||
switch thunkKind {
|
||||
case .noThunk: bridged.setThunk(.IsNotThunk)
|
||||
case .thunk: bridged.setThunk(.IsThunk)
|
||||
case .reabstractionThunk: bridged.setThunk(.IsReabstractionThunk)
|
||||
case .signatureOptimizedThunk: bridged.setThunk(.IsSignatureOptimizedThunk)
|
||||
}
|
||||
}
|
||||
|
||||
public var accessorKindName: String? {
|
||||
guard bridged.isAccessor() else {
|
||||
@@ -260,6 +274,10 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
|
||||
public var needsStackProtection: Bool {
|
||||
bridged.needsStackProtection()
|
||||
}
|
||||
public func set(needStackProtection: Bool, _ context: some MutatingContext) {
|
||||
context.notifyEffectsChanged()
|
||||
bridged.setNeedStackProtection(needStackProtection)
|
||||
}
|
||||
|
||||
public var isDeinitBarrier: Bool {
|
||||
effects.sideEffects?.global.isDeinitBarrier ?? true
|
||||
@@ -285,6 +303,10 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
|
||||
default: fatalError("unknown performance constraint")
|
||||
}
|
||||
}
|
||||
public func set(isPerformanceConstraint: Bool, _ context: some MutatingContext) {
|
||||
context.notifyEffectsChanged()
|
||||
bridged.setIsPerformanceConstraint(isPerformanceConstraint)
|
||||
}
|
||||
|
||||
public enum InlineStrategy {
|
||||
case automatic
|
||||
@@ -460,8 +482,8 @@ extension Function {
|
||||
}
|
||||
}
|
||||
|
||||
// Only to be called by PassContext
|
||||
public func _modifyEffects(_ body: (inout FunctionEffects) -> ()) {
|
||||
public func modifyEffects(_ context: some MutatingContext, _ body: (inout FunctionEffects) -> ()) {
|
||||
context.notifyEffectsChanged()
|
||||
body(&effects)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,15 @@ public class Instruction : CustomStringConvertible, Hashable {
|
||||
return allOperands[(allOperands.count - typeOperands.count) ..< allOperands.count]
|
||||
}
|
||||
|
||||
public final func setOperand(at index : Int, to value: Value, _ context: some MutatingContext) {
|
||||
if let apply = self as? FullApplySite, apply.isCallee(operand: operands[index]) {
|
||||
context.notifyCallsChanged()
|
||||
}
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.setOperand(index, value.bridged)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
|
||||
fileprivate var resultCount: Int { 0 }
|
||||
fileprivate func getResult(index: Int) -> Value { fatalError() }
|
||||
|
||||
@@ -83,6 +92,11 @@ public class Instruction : CustomStringConvertible, Hashable {
|
||||
return Location(bridged: bridged.getLocation())
|
||||
}
|
||||
|
||||
public final func move(before otherInstruction: Instruction, _ context: some MutatingContext) {
|
||||
BridgedContext.moveInstructionBefore(bridged, otherInstruction.bridged)
|
||||
context.notifyInstructionsChanged()
|
||||
}
|
||||
|
||||
public var mayTrap: Bool { false }
|
||||
|
||||
final public var mayHaveSideEffects: Bool {
|
||||
@@ -206,6 +220,12 @@ public class SingleValueInstruction : Instruction, Value {
|
||||
}
|
||||
|
||||
public var isLexical: Bool { false }
|
||||
|
||||
/// Replaces all uses with `replacement` and then erases the instruction.
|
||||
public final func replace(with replacement: Value, _ context: some MutatingContext) {
|
||||
uses.replaceAll(with: replacement, context)
|
||||
context.erase(instruction: self)
|
||||
}
|
||||
}
|
||||
|
||||
public final class MultipleValueInstructionResult : Value, Hashable {
|
||||
@@ -247,6 +267,14 @@ public class MultipleValueInstruction : Instruction {
|
||||
fileprivate final override func getResult(index: Int) -> Value {
|
||||
bridged.MultipleValueInstruction_getResult(index).result
|
||||
}
|
||||
|
||||
/// Replaces all uses with the result of `replacement` and then erases the instruction.
|
||||
public final func replace(with replacement: MultipleValueInstruction, _ context: some MutatingContext) {
|
||||
for (origResult, newResult) in zip(self.results, replacement.results) {
|
||||
origResult.uses.replaceAll(with: newResult, context)
|
||||
}
|
||||
context.erase(instruction: self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Instructions, which have a single operand (not including type-dependent operands).
|
||||
@@ -333,9 +361,20 @@ final public class CopyAddrInst : Instruction, SourceDestAddrInstruction {
|
||||
public var isTakeOfSource: Bool {
|
||||
bridged.CopyAddrInst_isTakeOfSrc()
|
||||
}
|
||||
public func set(isTakeOfSource: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.CopyAddrInst_setIsTakeOfSrc(isTakeOfSource)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
|
||||
public var isInitializationOfDestination: Bool {
|
||||
bridged.CopyAddrInst_isInitializationOfDest()
|
||||
}
|
||||
public func set(isInitializationOfDestination: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.CopyAddrInst_setIsInitializationOfDest(isInitializationOfDestination)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
final public class ExplicitCopyAddrInst : Instruction, SourceDestAddrInstruction {
|
||||
@@ -563,6 +602,12 @@ final public class RebindMemoryInst : SingleValueInstruction {}
|
||||
|
||||
public class RefCountingInst : Instruction, UnaryInstruction {
|
||||
public var isAtomic: Bool { bridged.RefCountingInst_getIsAtomic() }
|
||||
|
||||
public final func setAtomicity(isAtomic: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.RefCountingInst_setIsAtomic(isAtomic)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
final public class StrongRetainInst : RefCountingInst {
|
||||
@@ -675,6 +720,11 @@ final public class LoadInst : SingleValueInstruction, LoadInstruction {
|
||||
public var loadOwnership: LoadOwnership {
|
||||
LoadOwnership(rawValue: bridged.LoadInst_getLoadOwnership())!
|
||||
}
|
||||
public func set(ownership: LoadInst.LoadOwnership, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.LoadInst_setOwnership(ownership.rawValue)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
final public class LoadWeakInst : SingleValueInstruction, LoadInstruction {}
|
||||
@@ -763,6 +813,11 @@ class PointerToAddressInst : SingleValueInstruction, UnaryInstruction {
|
||||
}
|
||||
return Int(exactly: maybeAlign)
|
||||
}
|
||||
public func set(alignment: Int?, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.PointerToAddressInst_setAlignment(UInt64(alignment ?? 0))
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
public protocol IndexingInstruction: SingleValueInstruction {
|
||||
@@ -896,10 +951,22 @@ final public class GlobalAddrInst : GlobalAccessInstruction, VarDeclInstruction
|
||||
public var dependencyToken: Value? {
|
||||
operands.count == 1 ? operands[0].value : nil
|
||||
}
|
||||
|
||||
public func clearToken(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.GlobalAddrInst_clearToken()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
final public class GlobalValueInst : GlobalAccessInstruction {
|
||||
public var isBare: Bool { bridged.GlobalValueInst_isBare() }
|
||||
|
||||
public func setIsBare(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.GlobalValueInst_setIsBare()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
final public class BaseAddrForOffsetInst : SingleValueInstruction {}
|
||||
@@ -1016,6 +1083,12 @@ final public class RefElementAddrInst : SingleValueInstruction, UnaryInstruction
|
||||
|
||||
public var isImmutable: Bool { bridged.RefElementAddrInst_isImmutable() }
|
||||
|
||||
public func set(isImmutable: Bool, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.RefElementAddrInst_setImmutable(isImmutable)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
|
||||
public var varDecl: VarDecl? {
|
||||
bridged.RefElementAddr_getDecl().getAs(VarDecl.self)
|
||||
}
|
||||
@@ -1127,6 +1200,17 @@ extension MarkDependenceInstruction {
|
||||
public var valueOrAddress: Value { valueOrAddressOperand.value }
|
||||
public var baseOperand: Operand { operands[1] }
|
||||
public var base: Value { baseOperand.value }
|
||||
|
||||
public func resolveToNonEscaping(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.MarkDependenceInstruction_resolveToNonEscaping()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
public func settleToEscaping(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.MarkDependenceInstruction_settleToEscaping()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
final public class MarkDependenceInst : SingleValueInstruction, MarkDependenceInstruction {
|
||||
@@ -1404,6 +1488,12 @@ public class AllocRefInstBase : SingleValueInstruction, Allocation {
|
||||
bridged.AllocRefInstBase_canAllocOnStack()
|
||||
}
|
||||
|
||||
public final func setIsStackAllocatable(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.AllocRefInstBase_setIsStackAllocatable()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
|
||||
final public var tailAllocatedCounts: OperandArray {
|
||||
let numTailTypes = bridged.AllocRefInstBase_getNumTailTypes()
|
||||
return operands[0..<numTailTypes]
|
||||
@@ -1416,6 +1506,12 @@ public class AllocRefInstBase : SingleValueInstruction, Allocation {
|
||||
|
||||
final public class AllocRefInst : AllocRefInstBase {
|
||||
public var isBare: Bool { bridged.AllocRefInst_isBare() }
|
||||
|
||||
public func setIsBare(_ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.AllocRefInst_setIsBare()
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
}
|
||||
|
||||
final public class AllocRefDynamicInst : AllocRefInstBase {
|
||||
@@ -1530,6 +1626,11 @@ final public class BeginAccessInst : SingleValueInstruction, UnaryInstruction {
|
||||
public var accessKind: AccessKind {
|
||||
AccessKind(rawValue: bridged.BeginAccessInst_getAccessKind())!
|
||||
}
|
||||
public func set(accessKind: BeginAccessInst.AccessKind, context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.BeginAccess_setAccessKind(accessKind.rawValue)
|
||||
context.notifyInstructionChanged(self)
|
||||
}
|
||||
|
||||
public var isStatic: Bool { bridged.BeginAccessInst_isStatic() }
|
||||
public var isUnsafe: Bool { bridged.BeginAccessInst_isUnsafe() }
|
||||
@@ -1691,6 +1792,11 @@ public class TermInst : Instruction {
|
||||
}
|
||||
|
||||
public var isFunctionExiting: Bool { false }
|
||||
|
||||
public final func replaceBranchTarget(from fromBlock: BasicBlock, to toBlock: BasicBlock, _ context: some MutatingContext) {
|
||||
context.notifyBranchesChanged()
|
||||
bridged.TermInst_replaceBranchTarget(fromBlock.bridged, toBlock.bridged)
|
||||
}
|
||||
}
|
||||
|
||||
final public class UnreachableInst : TermInst {
|
||||
|
||||
@@ -27,6 +27,10 @@ public struct Operand : CustomStringConvertible, NoReflectionChildren, Equatable
|
||||
|
||||
public var value: Value { bridged.getValue().value }
|
||||
|
||||
public func set(to value: Value, _ context: some MutatingContext) {
|
||||
instruction.setOperand(at: index, to: value, context)
|
||||
}
|
||||
|
||||
public static func ==(lhs: Operand, rhs: Operand) -> Bool {
|
||||
return lhs.bridged.op == rhs.bridged.op
|
||||
}
|
||||
@@ -45,6 +49,12 @@ public struct Operand : CustomStringConvertible, NoReflectionChildren, Equatable
|
||||
|
||||
public func canAccept(ownership: Ownership) -> Bool { bridged.canAcceptOwnership(ownership._bridged) }
|
||||
|
||||
public func changeOwnership(from: Ownership, to: Ownership, _ context: some MutatingContext) {
|
||||
context.notifyInstructionsChanged()
|
||||
bridged.changeOwnership(from._bridged, to._bridged)
|
||||
context.notifyInstructionChanged(instruction)
|
||||
}
|
||||
|
||||
public var description: String { "operand #\(index) of \(instruction)" }
|
||||
}
|
||||
|
||||
@@ -185,6 +195,12 @@ extension Sequence where Element == Operand {
|
||||
public func users<I: Instruction>(ofType: I.Type) -> LazyMapSequence<LazyFilterSequence<Self>, I> {
|
||||
self.lazy.filter{ $0.instruction is I }.lazy.map { $0.instruction as! I }
|
||||
}
|
||||
|
||||
public func replaceAll(with replacement: Value, _ context: some MutatingContext) {
|
||||
for use in self {
|
||||
use.set(to: replacement, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Value {
|
||||
|
||||
@@ -298,6 +298,10 @@ public final class Undef : Value {
|
||||
public var hasTrivialNonPointerType: Bool { false }
|
||||
|
||||
public var isLexical: Bool { false }
|
||||
|
||||
public static func get(type: Type, _ context: some MutatingContext) -> Undef {
|
||||
context._bridged.getSILUndef(type.bridged).value as! Undef
|
||||
}
|
||||
}
|
||||
|
||||
final class PlaceholderValue : Value {
|
||||
|
||||
Reference in New Issue
Block a user