mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[sil] Add the ability to mark a function with isolation just so we can write more concurrency tests in SIL.
Specifically, we write a string out like: sil [isolation "$REPRESENTATION OF ISOLATION"] @function : $@convention(thin) ... The idea is that by using a string, we avoid parsing issues of the isolation and have flexibility. I left in the way we put isolation into the comment above functions so I did not break any tests that rely on it. I also made it so that we only accept this with sil tests that pass in the flag "sil-print-function-isolation-info". I am going to for the next release put in a full real implementation of this that allows for actor isolation to become a true first class citizen in SIL. But for now this at least lets us write tests in the short term. Since this is temporary and behind a flag, I did not add support for serialization since this is just for writing textual SIL tests.
This commit is contained in:
@@ -680,11 +680,13 @@ static bool parseDeclSILOptional(
|
||||
SILFunction::Purpose *specialPurpose, Inline_t *inlineStrategy,
|
||||
OptimizationMode *optimizationMode, PerformanceConstraints *perfConstraints,
|
||||
bool *isPerformanceConstraint, bool *markedAsUsed, StringRef *section,
|
||||
bool *isLet, bool *isWeakImported, bool *needStackProtection, bool *isSpecialized,
|
||||
AvailabilityRange *availability, bool *isWithoutActuallyEscapingThunk,
|
||||
bool *isLet, bool *isWeakImported, bool *needStackProtection,
|
||||
bool *isSpecialized, AvailabilityRange *availability,
|
||||
bool *isWithoutActuallyEscapingThunk,
|
||||
SmallVectorImpl<std::string> *Semantics,
|
||||
SmallVectorImpl<ParsedSpecAttr> *SpecAttrs, ValueDecl **ClangDecl,
|
||||
EffectsKind *MRK, SILParser &SP, SILModule &M) {
|
||||
EffectsKind *MRK, ActorIsolation *actorIsolation, SILParser &SP,
|
||||
SILModule &M) {
|
||||
while (SP.P.consumeIf(tok::l_square)) {
|
||||
if (isLet && SP.P.Tok.is(tok::kw_let)) {
|
||||
*isLet = true;
|
||||
@@ -785,7 +787,27 @@ static bool parseDeclSILOptional(
|
||||
*isPerformanceConstraint = true;
|
||||
else if (markedAsUsed && SP.P.Tok.getText() == "used")
|
||||
*markedAsUsed = true;
|
||||
else if (section && SP.P.Tok.getText() == "section") {
|
||||
else if (actorIsolation && SP.P.Tok.getText() == "isolation") {
|
||||
SP.P.consumeToken(tok::identifier);
|
||||
if (SP.P.Tok.getKind() != tok::string_literal) {
|
||||
SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
|
||||
return true;
|
||||
}
|
||||
StringRef rawString = SP.P.Tok.getText().drop_front().drop_back();
|
||||
// TODO: By using a raw string here, we can perhaps put in a simple string
|
||||
// representation of an actor that can be parsed back. For now this is
|
||||
// just a quick hack so we can write tests.
|
||||
auto optIsolation = ActorIsolation::forSILString(
|
||||
SP.P.Context.getIdentifier(rawString).str());
|
||||
if (!optIsolation) {
|
||||
SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
|
||||
return true;
|
||||
}
|
||||
*actorIsolation = *optIsolation;
|
||||
SP.P.consumeToken(tok::string_literal);
|
||||
SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
|
||||
continue;
|
||||
} else if (section && SP.P.Tok.getText() == "section") {
|
||||
SP.P.consumeToken(tok::identifier);
|
||||
if (SP.P.Tok.getKind() != tok::string_literal) {
|
||||
SP.P.diagnose(SP.P.Tok, diag::expected_in_attribute_list);
|
||||
@@ -799,8 +821,7 @@ static bool parseDeclSILOptional(
|
||||
|
||||
SP.P.parseToken(tok::r_square, diag::expected_in_attribute_list);
|
||||
continue;
|
||||
}
|
||||
else if (inlineStrategy && SP.P.Tok.getText() == "always_inline")
|
||||
} else if (inlineStrategy && SP.P.Tok.getText() == "always_inline")
|
||||
*inlineStrategy = AlwaysInline;
|
||||
else if (MRK && SP.P.Tok.getText() == "readnone")
|
||||
*MRK = EffectsKind::ReadNone;
|
||||
@@ -7320,6 +7341,7 @@ bool SILParserState::parseDeclSIL(Parser &P) {
|
||||
SILFunction *DynamicallyReplacedFunction = nullptr;
|
||||
SILFunction *AdHocWitnessFunction = nullptr;
|
||||
Identifier objCReplacementFor;
|
||||
ActorIsolation actorIsolation;
|
||||
if (parseSILLinkage(FnLinkage, P) ||
|
||||
parseDeclSILOptional(
|
||||
&isTransparent, &isSerialized, &isCanonical, &hasOwnershipSSA,
|
||||
@@ -7330,8 +7352,9 @@ bool SILParserState::parseDeclSIL(Parser &P) {
|
||||
&objCReplacementFor, &specialPurpose, &inlineStrategy,
|
||||
&optimizationMode, &perfConstr, &isPerformanceConstraint,
|
||||
&markedAsUsed, §ion, nullptr, &isWeakImported,
|
||||
&needStackProtection, nullptr, &availability, &isWithoutActuallyEscapingThunk,
|
||||
&Semantics, &SpecAttrs, &ClangDecl, &MRK, FunctionState, M) ||
|
||||
&needStackProtection, nullptr, &availability,
|
||||
&isWithoutActuallyEscapingThunk, &Semantics, &SpecAttrs, &ClangDecl,
|
||||
&MRK, &actorIsolation, FunctionState, M) ||
|
||||
P.parseToken(tok::at_sign, diag::expected_sil_function_name) ||
|
||||
P.parseIdentifier(FnName, FnNameLoc, /*diagnoseDollarPrefix=*/false,
|
||||
diag::expected_sil_function_name) ||
|
||||
@@ -7391,6 +7414,8 @@ bool SILParserState::parseDeclSIL(Parser &P) {
|
||||
for (auto &Attr : Semantics) {
|
||||
FunctionState.F->addSemanticsAttr(Attr);
|
||||
}
|
||||
if (actorIsolation)
|
||||
FunctionState.F->setActorIsolation(actorIsolation);
|
||||
// Now that we have a SILFunction parse the body, if present.
|
||||
|
||||
bool isDefinition = false;
|
||||
@@ -7580,11 +7605,11 @@ bool SILParserState::parseSILGlobal(Parser &P) {
|
||||
|
||||
SILParser State(P);
|
||||
if (parseSILLinkage(GlobalLinkage, P) ||
|
||||
parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr,
|
||||
parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, &isLet,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
&isLet, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, State, M) ||
|
||||
P.parseToken(tok::at_sign, diag::expected_sil_value_name) ||
|
||||
P.parseIdentifier(GlobalName, NameLoc, /*diagnoseDollarPrefix=*/false,
|
||||
@@ -7638,7 +7663,7 @@ bool SILParserState::parseSILProperty(Parser &P) {
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, SP, M))
|
||||
nullptr, nullptr, nullptr, nullptr, SP, M))
|
||||
return true;
|
||||
|
||||
ValueDecl *VD;
|
||||
@@ -7708,7 +7733,7 @@ bool SILParserState::parseSILVTable(Parser &P) {
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, VTableState, M))
|
||||
nullptr, nullptr, nullptr, nullptr, VTableState, M))
|
||||
return true;
|
||||
|
||||
|
||||
@@ -7831,7 +7856,8 @@ bool SILParserState::parseSILMoveOnlyDeinit(Parser &parser) {
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, moveOnlyDeinitTableState, M))
|
||||
nullptr, nullptr, nullptr, nullptr,
|
||||
moveOnlyDeinitTableState, M))
|
||||
return true;
|
||||
|
||||
// Parse the class name.
|
||||
@@ -8371,12 +8397,12 @@ bool SILParserState::parseSILWitnessTable(Parser &P) {
|
||||
|
||||
SerializedKind_t isSerialized = IsNotSerialized;
|
||||
bool isSpecialized = false;
|
||||
if (parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, &isSpecialized, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, WitnessState, M))
|
||||
if (parseDeclSILOptional(
|
||||
nullptr, &isSerialized, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, &isSpecialized, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, WitnessState, M))
|
||||
return true;
|
||||
|
||||
// Parse the protocol conformance.
|
||||
|
||||
Reference in New Issue
Block a user