Skip to content

[SIL] InitAccessors: Support assign_or_init in textual SIL #67593

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

Merged
merged 8 commits into from
Jul 31, 2023
6 changes: 4 additions & 2 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -956,13 +956,15 @@ class SILBuilder {
}

AssignOrInitInst *createAssignOrInit(SILLocation Loc,
VarDecl *Property,
SILValue Self,
SILValue Src,
SILValue Initializer,
SILValue Setter,
AssignOrInitInst::Mode Mode) {
return insert(new (getModule()) AssignOrInitInst(
getSILDebugLocation(Loc), Self, Src, Initializer, Setter, Mode));
return insert(new (getModule())
AssignOrInitInst(getSILDebugLocation(Loc), Property, Self,
Src, Initializer, Setter, Mode));
}

StoreBorrowInst *createStoreBorrow(SILLocation Loc, SILValue Src,
Expand Down
1 change: 1 addition & 0 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,7 @@ void SILCloner<ImplClass>::visitAssignOrInitInst(AssignOrInitInst *Inst) {
recordClonedInstruction(
Inst, getBuilder().createAssignOrInit(
getOpLocation(Inst->getLoc()),
Inst->getProperty(),
getOpValue(Inst->getSelf()),
getOpValue(Inst->getSrc()),
getOpValue(Inst->getInitializer()),
Expand Down
9 changes: 7 additions & 2 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4820,6 +4820,9 @@ class AssignOrInitInst

FixedOperandList<4> Operands;

/// Property the init accessor is associated with.
VarDecl *Property;

/// Marks all of the properties in `initializes(...)` list that
/// have been initialized before this intruction to help Raw SIL
/// lowering to emit destroys.
Expand All @@ -4838,10 +4841,12 @@ class AssignOrInitInst
};

private:
AssignOrInitInst(SILDebugLocation DebugLoc, SILValue Self, SILValue Src,
SILValue Initializer, SILValue Setter, Mode mode);
AssignOrInitInst(SILDebugLocation DebugLoc, VarDecl *P, SILValue Self,
SILValue Src, SILValue Initializer, SILValue Setter,
Mode mode);

public:
VarDecl *getProperty() const { return Property; }
SILValue getSelf() const { return Operands[0].get(); }
SILValue getSrc() const { return Operands[1].get(); }
SILValue getInitializer() const { return Operands[2].get(); }
Expand Down
9 changes: 9 additions & 0 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
}
}

if (auto *accessor = dyn_cast<AccessorDecl>(D)) {
if (accessor->isInitAccessor() && !options.PrintForSIL)
return false;
}

return ShouldPrintChecker::shouldPrint(D, options);
}
};
Expand Down Expand Up @@ -2259,8 +2264,12 @@ void PrintAST::printAccessors(const AbstractStorageDecl *ASD) {
accessorsToPrint.push_back(Accessor);
};

if (ASD->hasInitAccessor())
AddAccessorToPrint(AccessorKind::Init);

if (PrintAbstract) {
AddAccessorToPrint(AccessorKind::Get);

if (ASD->supportsMutation())
AddAccessorToPrint(AccessorKind::Set);
} else {
Expand Down
26 changes: 26 additions & 0 deletions lib/AST/Attr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,32 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
break;
}

case DAK_StorageRestrictions: {
auto *attr = cast<StorageRestrictionsAttr>(this);
Printer.printAttrName("@storageRestrictions");
Printer << "(";

auto initializes = attr->getInitializesNames();
auto accesses = attr->getAccessesNames();

bool needsComma = !initializes.empty() && !accesses.empty();

if (!initializes.empty()) {
Printer << "initializes: ";
interleave(initializes, Printer, ", ");
}

if (needsComma)
Printer << ", ";

if (!accesses.empty()) {
Printer << "accesses: ";
interleave(accesses, Printer, ", ");
}
Printer << ")";
break;
}

case DAK_Count:
llvm_unreachable("exceed declaration attribute kinds");

Expand Down
9 changes: 6 additions & 3 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7281,7 +7281,7 @@ static void diagnoseRedundantAccessors(Parser &P, SourceLoc loc,
/*already*/ true);
}

static bool isAllowedInProtocolRequirement(AccessorKind kind) {
static bool isAllowedInProtocolRequirement(AccessorKind kind, bool forSIL) {
switch (kind) {
case AccessorKind::Get:
case AccessorKind::Set:
Expand All @@ -7293,8 +7293,10 @@ static bool isAllowedInProtocolRequirement(AccessorKind kind) {
case AccessorKind::DidSet:
case AccessorKind::Read:
case AccessorKind::Modify:
case AccessorKind::Init:
return false;

case AccessorKind::Init:
return forSIL;
}
llvm_unreachable("bad accessor kind");
}
Expand Down Expand Up @@ -7688,7 +7690,8 @@ ParserStatus Parser::parseGetSet(ParseDeclOptions Flags, ParameterList *Indices,

// For now, immediately reject illegal accessors in protocols just to
// avoid having to deal with them everywhere.
if (parsingLimitedSyntax && !isAllowedInProtocolRequirement(Kind)) {
if (parsingLimitedSyntax &&
!isAllowedInProtocolRequirement(Kind, SF.Kind == SourceFileKind::SIL)) {
diagnose(Loc, diag::expected_getset_in_protocol);
continue;
}
Expand Down
25 changes: 7 additions & 18 deletions lib/SIL/IR/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1259,12 +1259,13 @@ AssignByWrapperInst::AssignByWrapperInst(SILDebugLocation Loc,
sharedUInt8().AssignByWrapperInst.mode = uint8_t(mode);
}

AssignOrInitInst::AssignOrInitInst(SILDebugLocation Loc, SILValue Self,
SILValue Src, SILValue Initializer,
SILValue Setter, AssignOrInitInst::Mode Mode)
AssignOrInitInst::AssignOrInitInst(SILDebugLocation Loc, VarDecl *P,
SILValue Self, SILValue Src,
SILValue Initializer, SILValue Setter,
AssignOrInitInst::Mode Mode)
: InstructionBase<SILInstructionKind::AssignOrInitInst,
NonValueInstruction>(Loc),
Operands(this, Self, Src, Initializer, Setter) {
Operands(this, Self, Src, Initializer, Setter), Property(P) {
assert(Initializer->getType().is<SILFunctionType>());
sharedUInt8().AssignOrInitInst.mode = uint8_t(Mode);
Assignments.resize(getNumInitializedProperties());
Expand All @@ -1291,23 +1292,11 @@ bool AssignOrInitInst::isPropertyAlreadyInitialized(unsigned propertyIdx) {
}

StringRef AssignOrInitInst::getPropertyName() const {
auto *accessor = getReferencedInitAccessor();
assert(accessor);
return cast<VarDecl>(accessor->getStorage())->getNameStr();
return Property->getNameStr();
}

AccessorDecl *AssignOrInitInst::getReferencedInitAccessor() const {
SILValue initRef = getInitializer();
SILFunction *accessorFn = nullptr;

if (auto *PAI = dyn_cast<PartialApplyInst>(initRef)) {
accessorFn = PAI->getReferencedFunctionOrNull();
} else {
accessorFn = cast<FunctionRefInst>(initRef)->getReferencedFunctionOrNull();
}

assert(accessorFn);
return dyn_cast_or_null<AccessorDecl>(accessorFn->getDeclContext());
return Property->getOpaqueAccessor(AccessorKind::Init);
}

unsigned AssignOrInitInst::getNumInitializedProperties() const {
Expand Down
6 changes: 5 additions & 1 deletion lib/SIL/IR/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1806,7 +1806,11 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
}
}

*this << "self " << getIDAndType(AI->getSelf());
*this << "#";
printFullContext(AI->getProperty()->getDeclContext(), PrintState.OS);
*this << AI->getPropertyName();

*this << ", self " << getIDAndType(AI->getSelf());
*this << ", value " << getIDAndType(AI->getSrc());
*this << ", init " << getIDAndType(AI->getInitializer())
<< ", set " << getIDAndType(AI->getSetter());
Expand Down
6 changes: 5 additions & 1 deletion lib/SIL/Parser/ParseSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4745,12 +4745,15 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
}

case SILInstructionKind::AssignOrInitInst: {
ValueDecl *Prop;
SILValue Self, Src, InitFn, SetFn;
AssignOrInitInst::Mode Mode;
llvm::SmallVector<unsigned, 2> assignments;

if (parseAssignOrInitMode(Mode, *this) ||
parseAssignOrInitAssignments(assignments, *this) ||
parseSILDottedPath(Prop) ||
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
parseVerbatim("self") || parseTypedValueRef(Self, B) ||
P.parseToken(tok::comma, diag::expected_tok_in_sil_instr, ",") ||
parseVerbatim("value") || parseTypedValueRef(Src, B) ||
Expand All @@ -4761,7 +4764,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
parseSILDebugLocation(InstLoc, B))
return true;

auto *AI = B.createAssignOrInit(InstLoc, Self, Src, InitFn, SetFn, Mode);
auto *AI = B.createAssignOrInit(InstLoc, cast<VarDecl>(Prop), Self, Src,
InitFn, SetFn, Mode);

for (unsigned index : assignments)
AI->markAsInitialized(index);
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/Verifier/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2736,7 +2736,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
SILFunctionConventions initConv(initTy, AI->getModule());

require(initConv.getNumIndirectSILResults() ==
AI->getInitializedProperties().size(),
AI->getNumInitializedProperties(),
"init function has invalid number of indirect results");
checkAssigOrInitInstAccessorArgs(Src->getType(), initConv);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/SILGen/SILGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,7 @@ void SILGenFunction::emitAssignOrInit(SILLocation loc, ManagedValue selfValue,
setterFRef = SILUndef::get(initFRef->getType(), F);
}

B.createAssignOrInit(loc, selfValue.getValue(), newValue.forward(*this),
initFRef, setterFRef, AssignOrInitInst::Unknown);
B.createAssignOrInit(loc, field, selfValue.getValue(),
newValue.forward(*this), initFRef, setterFRef,
AssignOrInitInst::Unknown);
}
Loading