1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
//===--- StaticInitCloner.swift --------------------------------------------==//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SIL
import OptimizerBridging
/// Clones the initializer value of a GlobalVariable.
///
/// Used to transitively clone "constant" instructions, including their operands,
/// from or to the static initializer value of a GlobalVariable.
///
struct StaticInitCloner<Context: MutatingContext> {
private var bridged: BridgedCloner
private let context: Context
private let cloningIntoFunction: Bool
init(cloneTo global: GlobalVariable, _ context: Context) {
self.bridged = BridgedCloner(global.bridged, context._bridged)
self.context = context
self.cloningIntoFunction = false
}
init(cloneBefore inst: Instruction, _ context: Context) {
self.bridged = BridgedCloner(inst.bridged, context._bridged)
self.context = context
self.cloningIntoFunction = true
}
mutating func deinitialize() {
bridged.destroy(context._bridged)
}
/// Transitively clones `value` including its defining instruction's operands.
mutating func clone(_ value: Value) -> Value {
if isCloned(value: value) {
return getClonedValue(of: value)
}
let inst = value.definingInstruction!
for op in inst.operands {
_ = clone(op.value)
}
bridged.clone(inst.bridged)
let clonedValue = getClonedValue(of: value)
if cloningIntoFunction {
context.notifyInstructionChanged(clonedValue.definingInstruction!)
}
return clonedValue
}
mutating func getClonedValue(of value: Value) -> Value {
bridged.getClonedValue(value.bridged).value
}
func isCloned(value: Value) -> Bool {
bridged.isValueCloned(value.bridged)
}
}
|