Skip to content

Commit 3992a8c

Browse files
committed
Print and parse the [canonical] function attribute.
1 parent cf962e0 commit 3992a8c

23 files changed

+162
-129
lines changed

include/swift/SIL/SILFunction.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ class SILFunction
349349
/// SIL). If so, diagnostics should not be reapplied.
350350
bool wasDeserializedCanonical() const { return WasDeserializedCanonical; }
351351

352-
void setWasDeserializedCanonical() { WasDeserializedCanonical = true; }
352+
void setWasDeserializedCanonical(bool val = true) {
353+
WasDeserializedCanonical = val;
354+
}
353355

354356
/// Returns the calling convention used by this entry point.
355357
SILFunctionTypeRepresentation getRepresentation() const {

lib/ParseSIL/ParseSIL.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,7 @@ void SILParser::convertRequirements(SILFunction *F,
885885

886886
static bool parseDeclSILOptional(bool *isTransparent,
887887
IsSerialized_t *isSerialized,
888+
bool *isCanonical,
888889
IsThunk_t *isThunk, bool *isGlobalInit,
889890
Inline_t *inlineStrategy,
890891
OptimizationMode *optimizationMode,
@@ -909,6 +910,8 @@ static bool parseDeclSILOptional(bool *isTransparent,
909910
*isSerialized = IsSerialized;
910911
else if (isSerialized && SP.P.Tok.getText() == "serializable")
911912
*isSerialized = IsSerializable;
913+
else if (isCanonical && SP.P.Tok.getText() == "canonical")
914+
*isCanonical = true;
912915
else if (isThunk && SP.P.Tok.getText() == "thunk")
913916
*isThunk = IsThunk;
914917
else if (isThunk && SP.P.Tok.getText() == "reabstraction_thunk")
@@ -5118,6 +5121,7 @@ bool SILParserTUState::parseDeclSIL(Parser &P) {
51185121
Scope S(&P, ScopeKind::TopLevel);
51195122
bool isTransparent = false;
51205123
IsSerialized_t isSerialized = IsNotSerialized;
5124+
bool isCanonical = false;
51215125
IsThunk_t isThunk = IsNotThunk;
51225126
bool isGlobalInit = false, isWeakLinked = false;
51235127
Inline_t inlineStrategy = InlineDefault;
@@ -5127,7 +5131,8 @@ bool SILParserTUState::parseDeclSIL(Parser &P) {
51275131
ValueDecl *ClangDecl = nullptr;
51285132
EffectsKind MRK = EffectsKind::Unspecified;
51295133
if (parseSILLinkage(FnLinkage, P) ||
5130-
parseDeclSILOptional(&isTransparent, &isSerialized, &isThunk, &isGlobalInit,
5134+
parseDeclSILOptional(&isTransparent, &isSerialized, &isCanonical,
5135+
&isThunk, &isGlobalInit,
51315136
&inlineStrategy, &optimizationMode, nullptr,
51325137
&isWeakLinked, &Semantics, &SpecAttrs,
51335138
&ClangDecl, &MRK, FunctionState) ||
@@ -5153,6 +5158,7 @@ bool SILParserTUState::parseDeclSIL(Parser &P) {
51535158
FunctionState.F->setBare(IsBare);
51545159
FunctionState.F->setTransparent(IsTransparent_t(isTransparent));
51555160
FunctionState.F->setSerialized(IsSerialized_t(isSerialized));
5161+
FunctionState.F->setWasDeserializedCanonical(isCanonical);
51565162
FunctionState.F->setThunk(IsThunk_t(isThunk));
51575163
FunctionState.F->setGlobalInit(isGlobalInit);
51585164
FunctionState.F->setWeakLinked(isWeakLinked);
@@ -5286,7 +5292,7 @@ bool SILParserTUState::parseSILGlobal(Parser &P) {
52865292
Scope S(&P, ScopeKind::TopLevel);
52875293
SILParser State(P);
52885294
if (parseSILLinkage(GlobalLinkage, P) ||
5289-
parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr,
5295+
parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
52905296
nullptr, nullptr, &isLet, nullptr, nullptr, nullptr,
52915297
nullptr, nullptr, State) ||
52925298
P.parseToken(tok::at_sign, diag::expected_sil_value_name) ||
@@ -5329,7 +5335,7 @@ bool SILParserTUState::parseSILProperty(Parser &P) {
53295335
SILParser SP(P);
53305336

53315337
IsSerialized_t Serialized = IsNotSerialized;
5332-
if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr,
5338+
if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr, nullptr,
53335339
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
53345340
nullptr, nullptr, SP))
53355341
return true;
@@ -5383,7 +5389,7 @@ bool SILParserTUState::parseSILVTable(Parser &P) {
53835389
SILParser VTableState(P);
53845390

53855391
IsSerialized_t Serialized = IsNotSerialized;
5386-
if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr,
5392+
if (parseDeclSILOptional(nullptr, &Serialized, nullptr, nullptr, nullptr,
53875393
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
53885394
nullptr, nullptr, VTableState))
53895395
return true;
@@ -5733,7 +5739,7 @@ bool SILParserTUState::parseSILWitnessTable(Parser &P) {
57335739
parseSILLinkage(Linkage, P);
57345740

57355741
IsSerialized_t isSerialized = IsNotSerialized;
5736-
if (parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr,
5742+
if (parseDeclSILOptional(nullptr, &isSerialized, nullptr, nullptr, nullptr,
57375743
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
57385744
nullptr, nullptr, WitnessState))
57395745
return true;

lib/SIL/SILPrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2324,6 +2324,15 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
23242324
OS << "] ";
23252325
}
23262326

2327+
// Handle functions that are deserialized from canonical SIL. Normally, we
2328+
// should emit SIL with the correct SIL stage, so preserving this attribute
2329+
// won't be necessary. But consider serializing raw SIL (either textual SIL or
2330+
// SIB) after importing canonical SIL from another module. If the imported
2331+
// functions are reserialized (e.g. shared linkage), then we must preserve
2332+
// this attribute.
2333+
if (WasDeserializedCanonical && getModule().getStage() == SILStage::Raw)
2334+
OS << "[canonical] ";
2335+
23272336
printName(OS);
23282337
OS << " : $";
23292338

test/Frontend/sil-merge-partial-modules.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,25 @@ public class CircleManager : ShapeManager {
4343

4444
// FIXME: Why is the definition order totally random?
4545

46-
// CHECK-LABEL: sil @$S4test17versionedFunctionyyF : $@convention(thin) () -> ()
46+
// CHECK-LABEL: sil [canonical] @$S4test17versionedFunctionyyF : $@convention(thin) () -> ()
4747

48-
// CHECK-LABEL: sil @$S4test9RectangleV4areaSfvg : $@convention(method) (Rectangle) -> Float
48+
// CHECK-LABEL: sil [canonical] @$S4test9RectangleV4areaSfvg : $@convention(method) (Rectangle) -> Float
4949

50-
// CHECK-LABEL: sil shared [serialized] @$S4test18inlineableFunctionyyFyycfU_ : $@convention(thin) () -> () {
50+
// CHECK-LABEL: sil shared [serialized] [canonical] @$S4test18inlineableFunctionyyFyycfU_ : $@convention(thin) () -> () {
5151
// CHECK: function_ref @$S4test17versionedFunctionyyF
5252
// CHECK: }
5353

54-
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] @$S4test9RectangleVAA5ShapeA2aDP4drawyyFTW : $@convention(witness_method: Shape) (@in_guaranteed Rectangle) -> () {
54+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [canonical] @$S4test9RectangleVAA5ShapeA2aDP4drawyyFTW : $@convention(witness_method: Shape) (@in_guaranteed Rectangle) -> () {
5555
// CHECK: function_ref @$S4test14publicFunctionyyF
5656
// CHECK: }
5757

58-
// CHECK-LABEL: sil [serialized] @$S4test18inlineableFunctionyyF : $@convention(thin) () -> () {
58+
// CHECK-LABEL: sil [serialized] [canonical] @$S4test18inlineableFunctionyyF : $@convention(thin) () -> () {
5959
// CHECK: function_ref @$S4test18inlineableFunctionyyFyycfU_
6060
// CHECK: }
6161

62-
// CHECK-LABEL: sil @$S4test14publicFunctionyyF : $@convention(thin) () -> ()
62+
// CHECK-LABEL: sil [canonical] @$S4test14publicFunctionyyF : $@convention(thin) () -> ()
6363

64-
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] @$S4test9RectangleVAA5ShapeA2aDP4areaSfvgTW : $@convention(witness_method: Shape) (@in_guaranteed Rectangle) -> Float {
64+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [canonical] @$S4test9RectangleVAA5ShapeA2aDP4areaSfvgTW : $@convention(witness_method: Shape) (@in_guaranteed Rectangle) -> Float {
6565
// CHECK: function_ref @$S4test9RectangleV4areaSfvg
6666
// CHECK: }
6767

test/SIL/Parser/stage.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module %s -O -parse-stdlib -parse-as-library -emit-module -o %t/stage.swiftmodule
3+
// RUN: %target-sil-opt %t/stage.swiftmodule -disable-sil-linking -sil-disable-ast-dump -o %t/stage.sil
4+
// RUN: %target-sil-opt %t/stage.sil -o - | %FileCheck %s
5+
6+
// FIXME: We create all SIL modules in the 'raw' stage regardless of the input
7+
// kind. If the primary input is a serialized module, we should assume the
8+
// canonical stage. Also .sib files should have their stage
9+
// serialized/deserialized.
10+
//
11+
// CHECK: sil_stage raw
12+
//
13+
// Verify that the '[canonical]' attribute was set.
14+
// CHECK: sil [serialized] [canonical] @$S5stage21functionToReserializeyyF : $@convention(thin) () -> () {
15+
@_inlineable
16+
public func functionToReserialize() {}

test/SIL/Serialization/deserialize_generic.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ bb0:
2121
}
2222

2323
// Make sure the function body is deserialized.
24-
// CHECK-LABEL: sil public_external [serialized] @$S11def_generic1AC23convertFromArrayLiteralyACyxGxd_tF : $@convention(method) <T> (@owned Array<T>, @guaranteed A<T>) -> @owned A<T> {
24+
// CHECK-LABEL: sil public_external [serialized] [canonical] @$S11def_generic1AC23convertFromArrayLiteralyACyxGxd_tF : $@convention(method) <T> (@owned Array<T>, @guaranteed A<T>) -> @owned A<T> {
2525
sil @$S11def_generic1AC23convertFromArrayLiteralyACyxGxd_tF : $@convention(method) <T> (@owned Array<T>, @guaranteed A<T>) -> @owned A<T>

test/SIL/Serialization/function_param_convention.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Swift
66
import FunctionInput
77

88
// Make sure we can deserialize a SIL function with these various attributes.
9-
// CHECK: sil public_external [serialized] @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X {
9+
// CHECK: sil public_external [serialized] [canonical] @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X {
1010

1111
sil @foo : $@convention(thin) (@in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X) -> @out X
1212

test/SIL/Serialization/public_non_abi.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ bb0:
2020
}
2121

2222
// Make sure the function body is deserialized.
23-
// CHECK-LABEL: sil shared_external [serialized] @public_non_abi_function : $@convention(thin) () -> ()
23+
// CHECK-LABEL: sil shared_external [serialized] [canonical] @public_non_abi_function : $@convention(thin) () -> ()
2424
// CHECK: return
2525
sil hidden_external [serialized] @public_non_abi_function : $@convention(thin) () -> ()

test/SIL/Serialization/visibility.sil

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,21 @@ import Builtin
2020

2121
// Check that all functions are defined/declared appropriately.
2222
// NEG-CHECK-NOT: sil [serialized] @public_external_function_test : $@convention(thin) () -> () {
23-
// CHECK-DAG: sil [serialized] @public_external_function_test : $@convention(thin) () -> ()
24-
// CHECK-DAG: sil hidden [serialized] @hidden_function_test : $@convention(thin) () -> () {
25-
// CHECK-DAG: sil [serialized] @references_public_function : $@convention(thin) () -> () {
26-
// CHECK-DAG: sil [serialized] @references_shared_function : $@convention(thin) () -> () {
27-
// CHECK-DAG: sil [serialized] @references_hidden_function : $@convention(thin) () -> () {
28-
// CHECK-DAG: sil [serialized] @references_private_function : $@convention(thin) () -> ()
29-
// CHECK-DAG: sil [serialized] @references_public_global : $@convention(thin) () -> () {
30-
// CHECK-DAG: sil [serialized] @references_shared_global : $@convention(thin) () -> () {
31-
// CHECK-DAG: sil [serialized] @references_hidden_global : $@convention(thin) () -> () {
32-
// CHECK-DAG: sil [serialized] @references_private_global : $@convention(thin) () -> ()
33-
// CHECK-DAG: sil hidden_external [serialized] @hidden_external_function_test : $@convention(thin) () -> ()
34-
// CHECK-DAG: sil [serialized] @public_function_test : $@convention(thin) () -> () {
35-
// CHECK-DAG: sil [serialized] @public_function : $@convention(thin) () -> () {
36-
// CHECK-DAG: sil hidden [serialized] @hidden_function : $@convention(thin) () -> () {
37-
// CHECK-DAG: sil shared_external [serialized] @shared_external_function_test : $@convention(thin) () -> ()
23+
// CHECK-DAG: sil [serialized] [canonical] @public_external_function_test : $@convention(thin) () -> ()
24+
// CHECK-DAG: sil hidden [serialized] [canonical] @hidden_function_test : $@convention(thin) () -> () {
25+
// CHECK-DAG: sil [serialized] [canonical] @references_public_function : $@convention(thin) () -> () {
26+
// CHECK-DAG: sil [serialized] [canonical] @references_shared_function : $@convention(thin) () -> () {
27+
// CHECK-DAG: sil [serialized] [canonical] @references_hidden_function : $@convention(thin) () -> () {
28+
// CHECK-DAG: sil [serialized] [canonical] @references_private_function : $@convention(thin) () -> ()
29+
// CHECK-DAG: sil [serialized] [canonical] @references_public_global : $@convention(thin) () -> () {
30+
// CHECK-DAG: sil [serialized] [canonical] @references_shared_global : $@convention(thin) () -> () {
31+
// CHECK-DAG: sil [serialized] [canonical] @references_hidden_global : $@convention(thin) () -> () {
32+
// CHECK-DAG: sil [serialized] [canonical] @references_private_global : $@convention(thin) () -> ()
33+
// CHECK-DAG: sil hidden_external [serialized] [canonical] @hidden_external_function_test : $@convention(thin) () -> ()
34+
// CHECK-DAG: sil [serialized] [canonical] @public_function_test : $@convention(thin) () -> () {
35+
// CHECK-DAG: sil [serialized] [canonical] @public_function : $@convention(thin) () -> () {
36+
// CHECK-DAG: sil hidden [serialized] [canonical] @hidden_function : $@convention(thin) () -> () {
37+
// CHECK-DAG: sil shared_external [serialized] [canonical] @shared_external_function_test : $@convention(thin) () -> ()
3838

3939
sil_global private [serialized] @private_global : $Builtin.Word
4040
sil_global [serialized] @public_global : $Builtin.Word

test/SILOptimizer/linker.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
// RUN: %target-swift-frontend -emit-module %S/Inputs/linker_pass_input.swift -o %t/Swift.swiftmodule -parse-stdlib -parse-as-library -module-name Swift -module-link-name swiftCore
33
// RUN: %target-swift-frontend %s -O -I %t -sil-debug-serialization -o - -emit-sil | %FileCheck %s
44

5-
// CHECK: sil public_external [serialized] @$Ss11doSomethingyyF : $@convention(thin) () -> () {
5+
// CHECK: sil public_external [serialized] [canonical] @$Ss11doSomethingyyF : $@convention(thin) () -> () {
66
doSomething()
77

88
// CHECK: sil @$Ss12doSomething2yyF : $@convention(thin) () -> ()
99
// CHECK-NOT: return
1010
doSomething2()
1111

12-
// CHECK: sil public_external [serialized] [noinline] @$Ss16callDoSomething3yyF
12+
// CHECK: sil public_external [serialized] [noinline] [canonical] @$Ss16callDoSomething3yyF
1313

14-
// CHECK: sil @unknown
14+
// CHECK: sil [canonical] @unknown
1515

16-
// CHECK: sil @$Ss1AVABycfC
16+
// CHECK: sil [canonical] @$Ss1AVABycfC
1717

18-
// CHECK: sil [noinline] @$Ss12doSomething3yyxlF
18+
// CHECK: sil [noinline] [canonical] @$Ss12doSomething3yyxlF
1919
// CHECK-NOT: return
2020

2121
callDoSomething3()

0 commit comments

Comments
 (0)