mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Swift SIL: add some instruction classes and APIs
* add `UnownedRetainInst` and `UnownedReleaseInst` * add `var value` to `RetainValueInst` and `ReleaseValueInst` * make the protocol `UnaryInstruction` be an `Instruction` * add `var Type.isValueTypeWithDeinit` * add `var Type.isUnownedStorageType` * add `var OperandArray.values`
This commit is contained in:
@@ -80,7 +80,7 @@ extension ApplySite {
|
||||
///
|
||||
/// This does not include the callee function operand.
|
||||
public var arguments: LazyMapSequence<OperandArray, Value> {
|
||||
argumentOperands.lazy.map { $0.value }
|
||||
argumentOperands.values
|
||||
}
|
||||
|
||||
public var substitutionMap: SubstitutionMap {
|
||||
|
||||
@@ -136,6 +136,18 @@ public struct Builder {
|
||||
return notifyNew(release.getAs(StrongReleaseInst.self))
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public func createUnownedRetain(operand: Value) -> UnownedRetainInst {
|
||||
let retain = bridged.createUnownedRetain(operand.bridged)
|
||||
return notifyNew(retain.getAs(UnownedRetainInst.self))
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public func createUnownedRelease(operand: Value) -> UnownedReleaseInst {
|
||||
let release = bridged.createUnownedRelease(operand.bridged)
|
||||
return notifyNew(release.getAs(UnownedReleaseInst.self))
|
||||
}
|
||||
|
||||
public func createFunctionRef(_ function: Function) -> FunctionRefInst {
|
||||
let functionRef = bridged.createFunctionRef(function.bridged)
|
||||
return notifyNew(functionRef.getAs(FunctionRefInst.self))
|
||||
|
||||
@@ -197,7 +197,7 @@ public class MultipleValueInstruction : Instruction {
|
||||
}
|
||||
|
||||
/// Instructions, which have a single operand.
|
||||
public protocol UnaryInstruction : AnyObject {
|
||||
public protocol UnaryInstruction : Instruction {
|
||||
var operands: OperandArray { get }
|
||||
var operand: Operand { get }
|
||||
}
|
||||
@@ -306,14 +306,24 @@ final public class StrongRetainInst : RefCountingInst {
|
||||
public var instance: Value { operand.value }
|
||||
}
|
||||
|
||||
final public class UnownedRetainInst : RefCountingInst {
|
||||
public var instance: Value { operand.value }
|
||||
}
|
||||
|
||||
final public class RetainValueInst : RefCountingInst {
|
||||
public var value: Value { return operand.value }
|
||||
}
|
||||
|
||||
final public class StrongReleaseInst : RefCountingInst {
|
||||
public var instance: Value { operand.value }
|
||||
}
|
||||
|
||||
final public class UnownedReleaseInst : RefCountingInst {
|
||||
public var instance: Value { operand.value }
|
||||
}
|
||||
|
||||
final public class ReleaseValueInst : RefCountingInst {
|
||||
public var value: Value { return operand.value }
|
||||
}
|
||||
|
||||
final public class DestroyValueInst : Instruction, UnaryInstruction {
|
||||
|
||||
@@ -76,6 +76,10 @@ public struct OperandArray : RandomAccessCollection, CustomReflectable {
|
||||
base: OptionalBridgedOperand(op: base.advancedBy(bounds.lowerBound).op),
|
||||
count: bounds.upperBound - bounds.lowerBound)
|
||||
}
|
||||
|
||||
public var values: LazyMapSequence<LazySequence<OperandArray>.Elements, Value> {
|
||||
self.lazy.map { $0.value }
|
||||
}
|
||||
}
|
||||
|
||||
public struct UseList : CollectionLikeSequence {
|
||||
|
||||
@@ -54,8 +54,10 @@ public func registerSILClasses() {
|
||||
register(EndApplyInst.self)
|
||||
register(AbortApplyInst.self)
|
||||
register(StrongRetainInst.self)
|
||||
register(UnownedRetainInst.self)
|
||||
register(RetainValueInst.self)
|
||||
register(StrongReleaseInst.self)
|
||||
register(UnownedReleaseInst.self)
|
||||
register(ReleaseValueInst.self)
|
||||
register(DestroyValueInst.self)
|
||||
register(DestroyAddrInst.self)
|
||||
|
||||
@@ -31,6 +31,10 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
|
||||
return !bridged.isNonTrivialOrContainsRawPointer(function.bridged.getFunction())
|
||||
}
|
||||
|
||||
/// True if this type is a value type (struct/enum) that requires deinitialization beyond
|
||||
/// destruction of its members.
|
||||
public var isValueTypeWithDeinit: Bool { bridged.isValueTypeWithDeinit() }
|
||||
|
||||
public func isLoadable(in function: Function) -> Bool {
|
||||
return bridged.isLoadable(function.bridged.getFunction())
|
||||
}
|
||||
@@ -39,6 +43,10 @@ public struct Type : CustomStringConvertible, NoReflectionChildren {
|
||||
return bridged.isReferenceCounted(function.bridged.getFunction())
|
||||
}
|
||||
|
||||
public var isUnownedStorageType: Bool {
|
||||
return bridged.isUnownedStorageType()
|
||||
}
|
||||
|
||||
public var hasArchetype: Bool { bridged.hasArchetype() }
|
||||
|
||||
public var isNominal: Bool { bridged.getNominalOrBoundGenericNominal() != nil }
|
||||
|
||||
@@ -1105,6 +1105,18 @@ struct BridgedBuilder{
|
||||
return {b.createStrongRelease(regularLoc(), op.getSILValue(), b.getDefaultAtomicity())};
|
||||
}
|
||||
|
||||
SWIFT_IMPORT_UNSAFE
|
||||
BridgedInstruction createUnownedRetain(BridgedValue op) const {
|
||||
auto b = builder();
|
||||
return {b.createUnownedRetain(regularLoc(), op.getSILValue(), b.getDefaultAtomicity())};
|
||||
}
|
||||
|
||||
SWIFT_IMPORT_UNSAFE
|
||||
BridgedInstruction createUnownedRelease(BridgedValue op) const {
|
||||
auto b = builder();
|
||||
return {b.createUnownedRelease(regularLoc(), op.getSILValue(), b.getDefaultAtomicity())};
|
||||
}
|
||||
|
||||
SWIFT_IMPORT_UNSAFE
|
||||
BridgedInstruction createFunctionRef(BridgedFunction function) const {
|
||||
return {builder().createFunctionRef(regularLoc(), function.getFunction())};
|
||||
|
||||
@@ -394,6 +394,8 @@ public:
|
||||
|
||||
bool isReferenceCounted(SILFunction *f) const;
|
||||
|
||||
bool isUnownedStorageType() const { return is<UnownedStorageType>(); }
|
||||
|
||||
/// Returns true if the referenced type is a function type that never
|
||||
/// returns.
|
||||
bool isNoReturnFunction(SILModule &M, TypeExpansionContext context) const;
|
||||
@@ -745,6 +747,10 @@ public:
|
||||
/// for a move only wrapped type.
|
||||
bool isPureMoveOnly() const;
|
||||
|
||||
/// Return true if this is a value type (struct/enum) that requires
|
||||
/// deinitialization beyond destruction of its members.
|
||||
bool isValueTypeWithDeinit() const;
|
||||
|
||||
/// Returns true if and only if this type is a first class move only
|
||||
/// type. NOTE: Returns false if the type is a move only wrapped type.
|
||||
bool isMoveOnlyNominalType() const;
|
||||
|
||||
@@ -1048,6 +1048,15 @@ bool SILType::isPureMoveOnly() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SILType::isValueTypeWithDeinit() const {
|
||||
// Do not look inside an aggregate type that has a user-deinit, for which
|
||||
// memberwise-destruction is not equivalent to aggregate destruction.
|
||||
if (auto *nominal = getNominalOrBoundGenericNominal()) {
|
||||
return nominal->getValueTypeDestructor() != nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SILType SILType::getInstanceTypeOfMetatype(SILFunction *function) const {
|
||||
auto metaType = castTo<MetatypeType>();
|
||||
CanType instanceTy = metaType.getInstanceType();
|
||||
|
||||
Reference in New Issue
Block a user