Skip to content

Commit

Permalink
Merge pull request #67593 from xedin/textual-sil-assign_or_init
Browse files Browse the repository at this point in the history
[SIL] InitAccessors: Support `assign_or_init` in textual SIL
  • Loading branch information
xedin committed Jul 31, 2023
2 parents 16c59fa + 7777ed5 commit a22bd27
Show file tree
Hide file tree
Showing 13 changed files with 195 additions and 54 deletions.
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 isAllowedWhenParsingLimitedSyntax(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 && !isAllowedWhenParsingLimitedSyntax(
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 @@ -4749,12 +4749,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 @@ -4765,7 +4768,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

0 comments on commit a22bd27

Please sign in to comment.