Skip to content

Commit c9d5e4b

Browse files
authored
Merge pull request #82038 from tshortli/language-modes-and-features-in-module-trace-6.2
[6.2] Frontend: Add language mode and enabled features to `.SWIFT_TRACE`
2 parents ed8d696 + f82c0b7 commit c9d5e4b

File tree

8 files changed

+169
-37
lines changed

8 files changed

+169
-37
lines changed

lib/FrontendTool/LoadedModuleTrace.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ struct LoadedModuleTraceFormat {
6565
unsigned Version;
6666
Identifier Name;
6767
std::string Arch;
68+
std::string LanguageMode;
69+
std::vector<StringRef> EnabledLanguageFeatures;
6870
bool StrictMemorySafety;
6971
std::vector<SwiftModuleTraceInfo> SwiftModules;
7072
std::vector<SwiftMacroTraceInfo> SwiftMacros;
@@ -107,6 +109,11 @@ template <> struct ObjectTraits<LoadedModuleTraceFormat> {
107109

108110
out.mapRequired("arch", contents.Arch);
109111

112+
out.mapRequired("languageMode", contents.LanguageMode);
113+
114+
out.mapRequired("enabledLanguageFeatures",
115+
contents.EnabledLanguageFeatures);
116+
110117
out.mapRequired("strictMemorySafety", contents.StrictMemorySafety);
111118

112119
// The 'swiftmodules' key is kept for backwards compatibility.
@@ -723,6 +730,38 @@ computeSwiftMacroTraceInfo(ASTContext &ctx, const DependencyTracker &depTracker,
723730
});
724731
}
725732

733+
static void computeEnabledFeatures(ASTContext &ctx,
734+
std::vector<StringRef> &enabledFeatures) {
735+
struct FeatureAndName {
736+
Feature feature;
737+
StringRef name;
738+
};
739+
740+
static const FeatureAndName features[] = {
741+
#define FEATURE_ENTRY(FeatureName) {Feature::FeatureName, #FeatureName},
742+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Version)
743+
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
744+
FEATURE_ENTRY(FeatureName)
745+
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
746+
FEATURE_ENTRY(FeatureName)
747+
#define OPTIONAL_LANGUAGE_FEATURE(FeatureName, SENumber, Version) \
748+
FEATURE_ENTRY(FeatureName)
749+
#include "swift/Basic/Features.def"
750+
};
751+
752+
for (auto &featureAndName : features) {
753+
if (ctx.LangOpts.hasFeature(featureAndName.feature))
754+
enabledFeatures.push_back(featureAndName.name);
755+
}
756+
757+
// FIXME: It would be nice if the features were added in sorted order instead.
758+
// However, std::sort is not constexpr until C++20.
759+
std::sort(enabledFeatures.begin(), enabledFeatures.end(),
760+
[](const StringRef &lhs, const StringRef &rhs) -> bool {
761+
return lhs.compare(rhs) < 0;
762+
});
763+
}
764+
726765
// [NOTE: Bailing-vs-crashing-in-trace-emission] There are certain edge cases
727766
// in trace emission where an invariant that you think should hold does not hold
728767
// in practice. For example, sometimes we have seen modules without any
@@ -785,12 +824,18 @@ bool swift::emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule,
785824
std::vector<SwiftMacroTraceInfo> swiftMacros;
786825
computeSwiftMacroTraceInfo(ctxt, *depTracker, swiftMacros);
787826

827+
std::vector<StringRef> enabledFeatures;
828+
computeEnabledFeatures(ctxt, enabledFeatures);
829+
788830
LoadedModuleTraceFormat trace = {
789831
/*version=*/LoadedModuleTraceFormat::CurrentVersion,
790832
/*name=*/mainModule->getName(),
791833
/*arch=*/ctxt.LangOpts.Target.getArchName().str(),
834+
ctxt.LangOpts.EffectiveLanguageVersion.asAPINotesVersionString(),
835+
enabledFeatures,
792836
mainModule ? mainModule->strictMemorySafety() : false,
793-
swiftModules, swiftMacros};
837+
swiftModules,
838+
swiftMacros};
794839

795840
// raw_fd_ostream is unbuffered, and we may have multiple processes writing,
796841
// so first write to memory and then dump the buffer to the trace file.

lib/IRGen/GenFunc.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,40 @@ CanType irgen::getArgumentLoweringType(CanType type, SILParameterInfo paramInfo,
862862
llvm_unreachable("unhandled convention");
863863
}
864864

865+
llvm::Constant *irgen::getCoroFrameAllocStubFn(IRGenModule &IGM) {
866+
return IGM.getOrCreateHelperFunction(
867+
"__swift_coroFrameAllocStub", IGM.Int8PtrTy,
868+
{IGM.SizeTy, IGM.Int64Ty},
869+
[&](IRGenFunction &IGF) {
870+
auto parameters = IGF.collectParameters();
871+
auto *size = parameters.claimNext();
872+
auto coroAllocPtr = IGF.IGM.getCoroFrameAllocFn();
873+
auto coroAllocFn = dyn_cast<llvm::Function>(coroAllocPtr);
874+
coroAllocFn->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
875+
auto *coroFrameAllocFn = IGF.IGM.getOpaquePtr(coroAllocPtr);
876+
auto *nullSwiftCoroFrameAlloc = IGF.Builder.CreateCmp(
877+
llvm::CmpInst::Predicate::ICMP_NE, coroFrameAllocFn,
878+
llvm::ConstantPointerNull::get(
879+
cast<llvm::PointerType>(coroFrameAllocFn->getType())));
880+
auto *coroFrameAllocReturn = IGF.createBasicBlock("return-coroFrameAlloc");
881+
auto *mallocReturn = IGF.createBasicBlock("return-malloc");
882+
IGF.Builder.CreateCondBr(nullSwiftCoroFrameAlloc, coroFrameAllocReturn, mallocReturn);
883+
884+
IGF.Builder.emitBlock(coroFrameAllocReturn);
885+
auto *mallocTypeId = parameters.claimNext();
886+
auto *coroFrameAllocCall = IGF.Builder.CreateCall(IGF.IGM.getCoroFrameAllocFunctionPointer(), {size, mallocTypeId});
887+
IGF.Builder.CreateRet(coroFrameAllocCall);
888+
889+
IGF.Builder.emitBlock(mallocReturn);
890+
auto *mallocCall = IGF.Builder.CreateCall(IGF.IGM.getMallocFunctionPointer(), {size});
891+
IGF.Builder.CreateRet(mallocCall);
892+
},
893+
/*setIsNoInline=*/false,
894+
/*forPrologue=*/false,
895+
/*isPerformanceConstraint=*/false,
896+
/*optionalLinkageOverride=*/nullptr, llvm::CallingConv::C);
897+
}
898+
865899
static Size getOffsetOfOpaqueIsolationField(IRGenModule &IGM,
866900
const LoadableTypeInfo &isolationTI) {
867901
auto offset = IGM.RefCountedStructSize;

lib/IRGen/GenFunc.h

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -64,39 +64,7 @@ namespace irgen {
6464

6565
/// Stub function that weakly links againt the swift_coroFrameAlloc
6666
/// function. This is required for back-deployment.
67-
static llvm::Constant *getCoroFrameAllocStubFn(IRGenModule &IGM) {
68-
return IGM.getOrCreateHelperFunction(
69-
"__swift_coroFrameAllocStub", IGM.Int8PtrTy,
70-
{IGM.SizeTy, IGM.Int64Ty},
71-
[&](IRGenFunction &IGF) {
72-
auto parameters = IGF.collectParameters();
73-
auto *size = parameters.claimNext();
74-
auto coroAllocPtr = IGF.IGM.getCoroFrameAllocFn();
75-
auto coroAllocFn = dyn_cast<llvm::Function>(coroAllocPtr);
76-
coroAllocFn->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
77-
auto *coroFrameAllocFn = IGF.IGM.getOpaquePtr(coroAllocPtr);
78-
auto *nullSwiftCoroFrameAlloc = IGF.Builder.CreateCmp(
79-
llvm::CmpInst::Predicate::ICMP_NE, coroFrameAllocFn,
80-
llvm::ConstantPointerNull::get(
81-
cast<llvm::PointerType>(coroFrameAllocFn->getType())));
82-
auto *coroFrameAllocReturn = IGF.createBasicBlock("return-coroFrameAlloc");
83-
auto *mallocReturn = IGF.createBasicBlock("return-malloc");
84-
IGF.Builder.CreateCondBr(nullSwiftCoroFrameAlloc, coroFrameAllocReturn, mallocReturn);
85-
86-
IGF.Builder.emitBlock(coroFrameAllocReturn);
87-
auto *mallocTypeId = parameters.claimNext();
88-
auto *coroFrameAllocCall = IGF.Builder.CreateCall(IGF.IGM.getCoroFrameAllocFunctionPointer(), {size, mallocTypeId});
89-
IGF.Builder.CreateRet(coroFrameAllocCall);
90-
91-
IGF.Builder.emitBlock(mallocReturn);
92-
auto *mallocCall = IGF.Builder.CreateCall(IGF.IGM.getMallocFunctionPointer(), {size});
93-
IGF.Builder.CreateRet(mallocCall);
94-
},
95-
/*setIsNoInline=*/false,
96-
/*forPrologue=*/false,
97-
/*isPerformanceConstraint=*/false,
98-
/*optionalLinkageOverride=*/nullptr, llvm::CallingConv::C);
99-
}
67+
llvm::Constant *getCoroFrameAllocStubFn(IRGenModule &IGM);
10068
} // end namespace irgen
10169
} // end namespace swift
10270

lib/SILOptimizer/Utils/SILIsolationInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
900900
if (auto *isolatedArg = llvm::cast_or_null<SILFunctionArgument>(
901901
fArg->getFunction()->maybeGetIsolatedArgument())) {
902902
auto astType = isolatedArg->getType().getASTType();
903-
if (auto *nomDecl = astType->lookThroughAllOptionalTypes()->getAnyActor()) {
903+
if (astType->lookThroughAllOptionalTypes()->getAnyActor()) {
904904
return SILIsolationInfo::getActorInstanceIsolated(fArg, isolatedArg);
905905
}
906906
}

lib/Sema/TypeCheckEffects.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,8 +1182,6 @@ class Classification {
11821182
PotentialEffectReason reason, SourceLoc loc,
11831183
bool skipTypeCheck,
11841184
std::optional<EffectKind> onlyEffect = std::nullopt) {
1185-
ASTContext &ctx = declRef.getDecl()->getASTContext();
1186-
11871185
Classification result;
11881186
bool considerAsync = !onlyEffect || *onlyEffect == EffectKind::Async;
11891187
bool considerThrows = !onlyEffect || *onlyEffect == EffectKind::Throws;

test/Driver/loaded_module_trace.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// CHECK: "version":2
1313
// CHECK: "name":"loaded_module_trace"
1414
// CHECK: "arch":"{{[^"]*}}"
15+
// CHECK: "languageMode":"4"
1516
// CHECK: "strictMemorySafety":false
1617
// CHECK: "swiftmodules":[
1718
// CHECK-DAG: "{{[^"]*\\[/\\]}}Module2.swiftmodule"
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend %s -emit-module -o /dev/null -swift-version 4 \
4+
// RUN: -emit-loaded-module-trace-path %t/swift4.trace.json
5+
// RUN: %FileCheck -check-prefix=CHECK-SWIFT4 %s < %t/swift4.trace.json
6+
7+
// RUN: %target-swift-frontend %s -emit-module -o /dev/null -swift-version 5 \
8+
// RUN: -emit-loaded-module-trace-path %t/swift5.trace.json
9+
// RUN: %FileCheck -check-prefix=CHECK-SWIFT5 %s < %t/swift5.trace.json
10+
11+
// RUN: %target-swift-frontend %s -emit-module -o /dev/null -swift-version 5 \
12+
// RUN: -emit-loaded-module-trace-path %t/swift5_and_features.trace.json \
13+
// RUN: -enable-experimental-feature ParserValidation \
14+
// RUN: -enable-upcoming-feature RegionBasedIsolation \
15+
// RUN: -strict-memory-safety
16+
// RUN: %FileCheck -check-prefix=CHECK-SWIFT5-PLUS %s < %t/swift5_and_features.trace.json
17+
18+
// RUN: %target-swift-frontend %s -emit-module -o /dev/null -swift-version 6 \
19+
// RUN: -emit-loaded-module-trace-path %t/swift6.trace.json
20+
// RUN: %FileCheck -check-prefix=CHECK-SWIFT6 %s < %t/swift6.trace.json
21+
22+
// NOTE: The matching of the enabledLanguageFeatures lists below is
23+
// intentionally inexact. There are few experimental features (ParserRoundTrip,
24+
// ParserValidation) that are enabled by default in asserts compilers but
25+
// otherwise disabled, so the enabled feature lists will sometimes contain
26+
// additional entries.
27+
28+
// REQUIRES: swift_feature_ParserValidation
29+
// REQUIRES: swift_feature_RegionBasedIsolation
30+
31+
// CHECK-SWIFT4: {
32+
// CHECK-SWIFT4: "version":2
33+
// CHECK-SWIFT4: "arch":"{{[^"]*}}"
34+
// CHECK-SWIFT4: "languageMode":"4"
35+
// CHECK-SWIFT4: "enabledLanguageFeatures":[
36+
// CHECK-SWIFT4: ]
37+
// CHECK-SWIFT4: "strictMemorySafety":false
38+
39+
// CHECK-SWIFT5: {
40+
// CHECK-SWIFT5: "version":2
41+
// CHECK-SWIFT5: "arch":"{{[^"]*}}"
42+
// CHECK-SWIFT5: "languageMode":"5"
43+
// CHECK-SWIFT5: "enabledLanguageFeatures":[
44+
// CHECK-SWIFT5: "NonfrozenEnumExhaustivity"
45+
// CHECK-SWIFT5: ]
46+
// CHECK-SWIFT5: "strictMemorySafety":false
47+
48+
// CHECK-SWIFT5-PLUS: {
49+
// CHECK-SWIFT5-PLUS: "version":2
50+
// CHECK-SWIFT5-PLUS: "arch":"{{[^"]*}}"
51+
// CHECK-SWIFT5-PLUS: "languageMode":"5"
52+
// CHECK-SWIFT5-PLUS: "enabledLanguageFeatures":[
53+
// CHECK-SWIFT5-PLUS: "NonfrozenEnumExhaustivity",
54+
// CHECK-SWIFT5-PLUS: "ParserValidation",
55+
// CHECK-SWIFT5-PLUS: "RegionBasedIsolation",
56+
// CHECK-SWIFT5-PLUS: "StrictMemorySafety"
57+
// CHECK-SWIFT5-PLUS: ]
58+
// CHECK-SWIFT5-PLUS: "strictMemorySafety":true
59+
60+
// CHECK-SWIFT6: {
61+
// CHECK-SWIFT6: "version":2
62+
// CHECK-SWIFT6: "arch":"{{[^"]*}}"
63+
// CHECK-SWIFT6: "languageMode":"6"
64+
// CHECK-SWIFT6: "enabledLanguageFeatures":[
65+
// CHECK-SWIFT6: "BareSlashRegexLiterals",
66+
// CHECK-SWIFT6: "ConciseMagicFile",
67+
// CHECK-SWIFT6: "DeprecateApplicationMain",
68+
// CHECK-SWIFT6: "DisableOutwardActorInference",
69+
// CHECK-SWIFT6: "DynamicActorIsolation",
70+
// CHECK-SWIFT6: "ForwardTrailingClosures",
71+
// CHECK-SWIFT6: "GlobalActorIsolatedTypesUsability",
72+
// CHECK-SWIFT6: "GlobalConcurrency",
73+
// CHECK-SWIFT6: "ImplicitOpenExistentials",
74+
// CHECK-SWIFT6: "ImportObjcForwardDeclarations",
75+
// CHECK-SWIFT6: "InferSendableFromCaptures",
76+
// CHECK-SWIFT6: "IsolatedDefaultValues",
77+
// CHECK-SWIFT6: "NonfrozenEnumExhaustivity",
78+
// CHECK-SWIFT6: "RegionBasedIsolation",
79+
// CHECK-SWIFT6: "StrictConcurrency"
80+
// CHECK-SWIFT6: ]
81+
// CHECK-SWIFT6: "strictMemorySafety":false
82+
83+
import Swift

test/Driver/loaded_module_trace_multifile.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
// CHECK: "version":2
1515
// CHECK: "name":"loaded_module_trace_multifile"
1616
// CHECK: "arch":"{{[^"]*}}"
17+
// CHECK: "languageMode":"4"
18+
// CHECK: "enabledLanguageFeatures":[
19+
// CHECK: ]
1720
// CHECK: "swiftmodules":[
1821
// CHECK-DAG: "{{[^"]*\\[/\\]}}Module2.swiftmodule"
1922
// CHECK-DAG: "{{[^"]*\\[/\\]}}Swift.swiftmodule{{(\\[/\\][^"]+[.]swiftmodule)?}}"

0 commit comments

Comments
 (0)