Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ownership] Define a new instruction copy_unmanaged_value. #26839

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/swift/AST/ReferenceStorage.def
Expand Up @@ -55,6 +55,7 @@
/// UNCHECKED_REF_STORAGE
/// Name##RetainValueInst
/// Name##ReleaseValueInst
/// Copy##Name##ValueInst
/// LOADABLE_REF_STORAGE
/// Ref*ToNameInst
/// Name*ToRefInst
Expand Down Expand Up @@ -98,6 +99,10 @@
/// storage type, and SOMETIMES_LOADABLE_CHECKED_REF_STORAGE needs *two*
/// TypeInfos to be created. One for the loadable scenario, and one for the
/// address-only scenario.
///
/// TODO: We should change Copy##Name##ValueInst to be defined on
/// LOADABLE_REF_STORAGE. It just will require us to go through, refactor, and
/// fix up this code.


#ifndef REF_STORAGE
Expand Down
35 changes: 18 additions & 17 deletions include/swift/SIL/SILBuilder.h
Expand Up @@ -896,17 +896,25 @@ class SILBuilder {
return insert(new (getModule()) \
Store##Name##Inst(getSILDebugLocation(Loc), value, dest, isInit)); \
}
#define LOADABLE_REF_STORAGE_HELPER(Name) \
Name##ToRefInst *create##Name##ToRef(SILLocation Loc, SILValue op, \
SILType ty) { \
return insert(new (getModule()) \
Name##ToRefInst(getSILDebugLocation(Loc), op, ty)); \
} \
RefTo##Name##Inst *createRefTo##Name(SILLocation Loc, SILValue op, \
SILType ty) { \
return insert(new (getModule()) \
RefTo##Name##Inst(getSILDebugLocation(Loc), op, ty)); \
#define LOADABLE_REF_STORAGE_HELPER(Name) \
Name##ToRefInst *create##Name##ToRef(SILLocation Loc, SILValue op, \
SILType ty) { \
return insert(new (getModule()) \
Name##ToRefInst(getSILDebugLocation(Loc), op, ty)); \
} \
RefTo##Name##Inst *createRefTo##Name(SILLocation Loc, SILValue op, \
SILType ty) { \
return insert(new (getModule()) \
RefTo##Name##Inst(getSILDebugLocation(Loc), op, ty)); \
} \
Copy##Name##ValueInst *createCopy##Name##Value(SILLocation Loc, \
SILValue operand) { \
auto type = getFunction().getLoweredType( \
operand->getType().getASTType().getReferenceStorageReferent()); \
return insert(new (getModule()) Copy##Name##ValueInst( \
getSILDebugLocation(Loc), operand, type)); \
}

#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
LOADABLE_REF_STORAGE_HELPER(Name) \
StrongRetain##Name##Inst *createStrongRetain##Name(SILLocation Loc, \
Expand All @@ -925,13 +933,6 @@ class SILBuilder {
Atomicity atomicity) { \
return insert(new (getModule()) \
Name##ReleaseInst(getSILDebugLocation(Loc), Operand, atomicity)); \
} \
Copy##Name##ValueInst *createCopy##Name##Value(SILLocation Loc, \
SILValue operand) { \
auto type = getFunction().getLoweredType( \
operand->getType().getASTType().getReferenceStorageReferent()); \
return insert(new (getModule()) \
Copy##Name##ValueInst(getSILDebugLocation(Loc), operand, type)); \
}
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, "...") \
Expand Down
16 changes: 8 additions & 8 deletions include/swift/SIL/SILCloner.h
Expand Up @@ -1308,6 +1308,14 @@ SILCloner<ImplClass>::visitDebugValueAddrInst(DebugValueAddrInst *Inst) {
Inst, getBuilder().create##Name##ToRef(getOpLocation(Inst->getLoc()), \
getOpValue(Inst->getOperand()), \
getOpType(Inst->getType()))); \
} \
template <typename ImplClass> \
void SILCloner<ImplClass>::visitCopy##Name##ValueInst( \
Copy##Name##ValueInst *Inst) { \
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); \
recordClonedInstruction(Inst, getBuilder().createCopy##Name##Value( \
getOpLocation(Inst->getLoc()), \
getOpValue(Inst->getOperand()))); \
}
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
LOADABLE_REF_STORAGE_HELPER(Name, name) \
Expand Down Expand Up @@ -1336,14 +1344,6 @@ SILCloner<ImplClass>::visitDebugValueAddrInst(DebugValueAddrInst *Inst) {
getOpLocation(Inst->getLoc()), \
getOpValue(Inst->getOperand()), \
Inst->getAtomicity())); \
} \
template <typename ImplClass> \
void SILCloner<ImplClass>::visitCopy##Name##ValueInst( \
Copy##Name##ValueInst *Inst) { \
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); \
recordClonedInstruction(Inst, getBuilder().createCopy##Name##Value( \
getOpLocation(Inst->getLoc()), \
getOpValue(Inst->getOperand()))); \
}
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, "...") \
Expand Down
28 changes: 19 additions & 9 deletions include/swift/SIL/SILInstruction.h
Expand Up @@ -6468,15 +6468,25 @@ class CopyValueInst
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {}
};

#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
class Copy##Name##ValueInst \
: public UnaryInstructionBase<SILInstructionKind::Copy##Name##ValueInst, \
SingleValueInstruction> { \
friend class SILBuilder; \
Copy##Name##ValueInst(SILDebugLocation DebugLoc, SILValue operand, \
SILType type) \
: UnaryInstructionBase(DebugLoc, operand, type) {} \
};
#define UNCHECKED_REF_STORAGE(Name, ...) \
class Copy##Name##ValueInst \
: public UnaryInstructionBase<SILInstructionKind::Copy##Name##ValueInst, \
SingleValueInstruction> { \
friend class SILBuilder; \
Copy##Name##ValueInst(SILDebugLocation DebugLoc, SILValue operand, \
SILType type) \
: UnaryInstructionBase(DebugLoc, operand, type) {} \
};

#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
class Copy##Name##ValueInst \
: public UnaryInstructionBase<SILInstructionKind::Copy##Name##ValueInst, \
SingleValueInstruction> { \
friend class SILBuilder; \
Copy##Name##ValueInst(SILDebugLocation DebugLoc, SILValue operand, \
SILType type) \
: UnaryInstructionBase(DebugLoc, operand, type) {} \
};
#include "swift/AST/ReferenceStorage.def"

class DestroyValueInst
Expand Down
3 changes: 3 additions & 0 deletions include/swift/SIL/SILNodes.def
Expand Up @@ -562,6 +562,9 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
SINGLE_VALUE_INST(CopyValueInst, copy_value,
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
#define UNCHECKED_REF_STORAGE(Name, name, ...) \
SINGLE_VALUE_INST(Copy##Name##ValueInst, copy_##name##_value, \
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
SINGLE_VALUE_INST(Copy##Name##ValueInst, copy_##name##_value, \
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/ModuleFormat.h
Expand Up @@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t SWIFTMODULE_VERSION_MINOR = 512; // extended types may be left as unbound generic types
const uint16_t SWIFTMODULE_VERSION_MINOR = 513; // Added copy_unmanaged_value.

using DeclIDField = BCFixed<31>;

Expand Down
44 changes: 34 additions & 10 deletions lib/IRGen/IRGenSIL.cpp
Expand Up @@ -1123,19 +1123,18 @@ class IRGenSILFunction :

void visitKeyPathInst(KeyPathInst *I);


#define LOADABLE_REF_STORAGE_HELPER(Name) \
void visitRefTo##Name##Inst(RefTo##Name##Inst *i); \
void visit##Name##ToRefInst(Name##ToRefInst *i);
#define LOADABLE_REF_STORAGE_HELPER(Name) \
void visitRefTo##Name##Inst(RefTo##Name##Inst *i); \
void visit##Name##ToRefInst(Name##ToRefInst *i); \
void visitCopy##Name##ValueInst(Copy##Name##ValueInst *i);
#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
void visitLoad##Name##Inst(Load##Name##Inst *i); \
void visitStore##Name##Inst(Store##Name##Inst *i);
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
LOADABLE_REF_STORAGE_HELPER(Name) \
void visitStrongRetain##Name##Inst(StrongRetain##Name##Inst *i); \
void visit##Name##RetainInst(Name##RetainInst *i); \
void visit##Name##ReleaseInst(Name##ReleaseInst *i); \
void visitCopy##Name##ValueInst(Copy##Name##ValueInst *i);
#define ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
LOADABLE_REF_STORAGE_HELPER(Name) \
void visitStrongRetain##Name##Inst(StrongRetain##Name##Inst *i); \
void visit##Name##RetainInst(Name##RetainInst *i); \
void visit##Name##ReleaseInst(Name##ReleaseInst *i);
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, "...") \
ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, "...")
Expand Down Expand Up @@ -3878,6 +3877,31 @@ static const ReferenceTypeInfo &getReferentTypeInfo(IRGenFunction &IGF,
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, "...") \
ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, name, "...")
#define UNCHECKED_REF_STORAGE(Name, name, ...) \
void IRGenSILFunction::visitCopy##Name##ValueInst( \
swift::Copy##Name##ValueInst *i) { \
Explosion in = getLoweredExplosion(i->getOperand()); \
auto silTy = i->getOperand()->getType(); \
auto ty = cast<Name##StorageType>(silTy.getASTType()); \
auto isOptional = bool(ty.getReferentType()->getOptionalObjectType()); \
auto &ti = getReferentTypeInfo(*this, silTy); \
/* Since we are unchecked, we just use strong retain here. We do not \
* perform any checks */ \
ti.strongRetain(*this, in, irgen::Atomicity::Atomic); \
/* Semantically we are just passing through the input parameter but as a \
*/ \
/* strong reference... at LLVM IR level these type differences don't */ \
/* matter. So just set the lowered explosion appropriately. */ \
Explosion output = getLoweredExplosion(i->getOperand()); \
if (isOptional) { \
auto values = output.claimAll(); \
output.reset(); \
for (auto value : values) { \
output.add(Builder.CreatePtrToInt(value, IGM.IntPtrTy)); \
} \
} \
setLoweredExplosion(i, output); \
}
#include "swift/AST/ReferenceStorage.def"
#undef COMMON_CHECKED_REF_STORAGE

Expand Down
1 change: 1 addition & 0 deletions lib/ParseSIL/ParseSIL.cpp
Expand Up @@ -2948,6 +2948,7 @@ bool SILParser::parseSILInstruction(SILBuilder &B) {
REFCOUNTING_INSTRUCTION(RetainValue)
REFCOUNTING_INSTRUCTION(ReleaseValueAddr)
REFCOUNTING_INSTRUCTION(RetainValueAddr)
#define UNCHECKED_REF_STORAGE(Name, ...) UNARY_INSTRUCTION(Copy##Name##Value)
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
REFCOUNTING_INSTRUCTION(StrongRetain##Name) \
REFCOUNTING_INSTRUCTION(Name##Retain) \
Expand Down
15 changes: 9 additions & 6 deletions lib/SIL/InstructionUtils.cpp
Expand Up @@ -324,12 +324,15 @@ bool swift::onlyAffectsRefCount(SILInstruction *user) {
case SILInstructionKind::StrongReleaseInst:
case SILInstructionKind::StrongRetainInst:
case SILInstructionKind::UnmanagedAutoreleaseValueInst:
case SILInstructionKind::UnmanagedReleaseValueInst:
case SILInstructionKind::UnmanagedRetainValueInst:
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Name##RetainInst: \
case SILInstructionKind::Name##ReleaseInst: \
case SILInstructionKind::StrongRetain##Name##Inst:
#define UNCHECKED_REF_STORAGE(Name, ...) \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the Unmanaged*ValueInst under UNCHECKED_REF_STORAGE (since Unmanaged is an unchecked ref storage).

case SILInstructionKind::Name##RetainValueInst: \
case SILInstructionKind::Name##ReleaseValueInst: \
case SILInstructionKind::Copy##Name##ValueInst:
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Name##RetainInst: \
case SILInstructionKind::Name##ReleaseInst: \
case SILInstructionKind::StrongRetain##Name##Inst: \
case SILInstructionKind::Copy##Name##ValueInst:
#include "swift/AST/ReferenceStorage.def"
return true;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/SIL/MemAccessUtils.cpp
Expand Up @@ -746,6 +746,8 @@ void swift::visitAccessedAddress(SILInstruction *I,
}
// Non-access cases: these are marked with memory side effects, but, by
// themselves, do not access formal memory.
#define UNCHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Copy##Name##ValueInst:
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Copy##Name##ValueInst:
#include "swift/AST/ReferenceStorage.def"
Expand Down
4 changes: 3 additions & 1 deletion lib/SIL/OperandOwnership.cpp
Expand Up @@ -284,7 +284,9 @@ ACCEPTS_ANY_OWNERSHIP_INST(ConvertEscapeToNoEscape)
ACCEPTS_ANY_OWNERSHIP_INST(RefTo##Name) \
ACCEPTS_ANY_OWNERSHIP_INST(Name##ToRef) \
ACCEPTS_ANY_OWNERSHIP_INST(Copy##Name##Value)
#define UNCHECKED_REF_STORAGE(Name, ...) ACCEPTS_ANY_OWNERSHIP_INST(RefTo##Name)
#define UNCHECKED_REF_STORAGE(Name, ...) \
ACCEPTS_ANY_OWNERSHIP_INST(RefTo##Name) \
ACCEPTS_ANY_OWNERSHIP_INST(Copy##Name##Value)
#include "swift/AST/ReferenceStorage.def"
#undef ACCEPTS_ANY_OWNERSHIP_INST

Expand Down
3 changes: 3 additions & 0 deletions lib/SIL/SILBuilder.cpp
Expand Up @@ -280,6 +280,9 @@ static bool couldReduceStrongRefcount(SILInstruction *Inst) {
#define SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Store##Name##Inst: \
ALWAYS_LOADABLE_CHECKED_REF_STORAGE(Name, "...")
#define UNCHECKED_REF_STORAGE(Name, ...) \
case SILInstructionKind::Copy##Name##ValueInst: \
return false;
#include "swift/AST/ReferenceStorage.def"
case SILInstructionKind::LoadInst:
case SILInstructionKind::StoreInst:
Expand Down
7 changes: 4 additions & 3 deletions lib/SIL/SILInstruction.cpp
Expand Up @@ -734,9 +734,10 @@ namespace {
return true;
}

#define LOADABLE_REF_STORAGE_HELPER(Name) \
bool visit##Name##ToRefInst(Name##ToRefInst *RHS) { return true; } \
bool visitRefTo##Name##Inst(RefTo##Name##Inst *RHS) { return true; }
#define LOADABLE_REF_STORAGE_HELPER(Name) \
bool visit##Name##ToRefInst(Name##ToRefInst *RHS) { return true; } \
bool visitRefTo##Name##Inst(RefTo##Name##Inst *RHS) { return true; } \
bool visitCopy##Name##ValueInst(Copy##Name##ValueInst *RHS) { return true; }
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
LOADABLE_REF_STORAGE_HELPER(Name) \
bool visitStrongRetain##Name##Inst(const StrongRetain##Name##Inst *RHS) { \
Expand Down
5 changes: 5 additions & 0 deletions lib/SIL/SILPrinter.cpp
Expand Up @@ -1538,6 +1538,11 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
*this << getIDAndType(I->getOperand());
}

#define UNCHECKED_REF_STORAGE(Name, ...) \
void visitCopy##Name##ValueInst(Copy##Name##ValueInst *I) { \
*this << getIDAndType(I->getOperand()); \
}

#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
void visitCopy##Name##ValueInst(Copy##Name##ValueInst *I) { \
*this << getIDAndType(I->getOperand()); \
Expand Down