Skip to content

Commit a6967e3

Browse files
authored
Merge pull request #70152 from zoecarver/three-new-perf-annotations
[opt] Add three new perf annotations: `@_noRuntime`, `@_noExistentials`, and `@_noObjCBridging`.
2 parents c46eb58 + 69498e2 commit a6967e3

File tree

14 files changed

+135
-12
lines changed

14 files changed

+135
-12
lines changed

SwiftCompilerSources/Sources/SIL/Function.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,19 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
203203
case none
204204
case noAllocations
205205
case noLocks
206+
case noRuntime
207+
case noExistentials
208+
case noObjCRuntime
206209
}
207210

208211
public var performanceConstraints: PerformanceConstraints {
209212
switch bridged.getPerformanceConstraints() {
210213
case .None: return .none
211214
case .NoAllocation: return .noAllocations
212215
case .NoLocks: return .noLocks
216+
case .NoRuntime: return .noRuntime
217+
case .NoExistentials: return .noExistentials
218+
case .NoObjCBridging: return .noObjCRuntime
213219
default: fatalError("unknown performance constraint")
214220
}
215221
}

include/swift/AST/Attr.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,15 @@ SIMPLE_DECL_ATTR(_staticExclusiveOnly, StaticExclusiveOnly,
536536
SIMPLE_DECL_ATTR(extractConstantsFromMembers, ExtractConstantsFromMembers,
537537
OnProtocol | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
538538
152)
539+
SIMPLE_DECL_ATTR(_noRuntime, NoRuntime,
540+
OnAbstractFunction | OnSubscript | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
541+
153)
542+
SIMPLE_DECL_ATTR(_noExistentials, NoExistentials,
543+
OnAbstractFunction | OnSubscript | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
544+
154)
545+
SIMPLE_DECL_ATTR(_noObjCBridging, NoObjCBridging,
546+
OnAbstractFunction | OnSubscript | UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove,
547+
155)
539548

540549
#undef TYPE_ATTR
541550
#undef DECL_ATTR_ALIAS

include/swift/AST/DiagnosticsSIL.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,10 @@ ERROR(embedded_swift_existential_type,none,
356356
"cannot use a value of protocol type %0 in embedded Swift", (Type))
357357
ERROR(embedded_swift_existential,none,
358358
"cannot use a value of protocol type in embedded Swift", ())
359+
ERROR(perf_diag_existential_type,none,
360+
"cannot use a value of protocol type %0 in @_noExistential function", (Type))
361+
ERROR(perf_diag_existential,none,
362+
"cannot use a value of protocol type in @_noExistential function", ())
359363
ERROR(embedded_swift_metatype_type,none,
360364
"cannot use metatype of type %0 in embedded Swift", (Type))
361365
ERROR(embedded_swift_metatype,none,

include/swift/SIL/SILBridging.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,10 @@ struct BridgedFunction {
302302
enum class PerformanceConstraints {
303303
None = 0,
304304
NoAllocation = 1,
305-
NoLocks = 2
305+
NoLocks = 2,
306+
NoRuntime = 3,
307+
NoExistentials = 4,
308+
NoObjCBridging = 5
306309
};
307310

308311
enum class InlineStrategy {

include/swift/SIL/SILFunction.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ enum class PerformanceConstraints : uint8_t {
8686
None = 0,
8787
NoAllocation = 1,
8888
NoLocks = 2,
89+
NoRuntime = 3,
90+
NoExistentials = 4,
91+
NoObjCBridging = 5
8992
};
9093

9194
class SILSpecializeAttr final {

lib/SIL/IR/SILFunctionBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ void SILFunctionBuilder::addFunctionAttributes(
193193
F->setPerfConstraints(PerformanceConstraints::NoLocks);
194194
} else if (Attrs.hasAttribute<NoAllocationAttr>()) {
195195
F->setPerfConstraints(PerformanceConstraints::NoAllocation);
196+
} else if (Attrs.hasAttribute<NoRuntimeAttr>()) {
197+
F->setPerfConstraints(PerformanceConstraints::NoRuntime);
198+
} else if (Attrs.hasAttribute<NoExistentialsAttr>()) {
199+
F->setPerfConstraints(PerformanceConstraints::NoExistentials);
200+
} else if (Attrs.hasAttribute<NoObjCBridgingAttr>()) {
201+
F->setPerfConstraints(PerformanceConstraints::NoObjCBridging);
196202
}
197203

198204
if (Attrs.hasAttribute<LexicalLifetimesAttr>()) {

lib/SIL/IR/SILPrinter.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3318,9 +3318,12 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
33183318

33193319
PerformanceConstraints perf = getPerfConstraints();
33203320
switch (perf) {
3321-
case PerformanceConstraints::None: break;
3322-
case PerformanceConstraints::NoLocks: OS << "[no_locks] "; break;
3323-
case PerformanceConstraints::NoAllocation: OS << "[no_allocation] "; break;
3321+
case PerformanceConstraints::None: break;
3322+
case PerformanceConstraints::NoLocks: OS << "[no_locks] "; break;
3323+
case PerformanceConstraints::NoAllocation: OS << "[no_allocation] "; break;
3324+
case PerformanceConstraints::NoRuntime: OS << "[no_runtime] "; break;
3325+
case PerformanceConstraints::NoExistentials: OS << "[no_existentials] "; break;
3326+
case PerformanceConstraints::NoObjCBridging: OS << "[no_objc_bridging] "; break;
33243327
}
33253328

33263329
if (getEffectsKind() == EffectsKind::ReadOnly)

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,12 @@ static bool parseDeclSILOptional(bool *isTransparent,
11491149
*perfConstraints = PerformanceConstraints::NoLocks;
11501150
else if (perfConstraints && SP.P.Tok.getText() == "no_allocation")
11511151
*perfConstraints = PerformanceConstraints::NoAllocation;
1152+
else if (perfConstraints && SP.P.Tok.getText() == "no_runtime")
1153+
*perfConstraints = PerformanceConstraints::NoRuntime;
1154+
else if (perfConstraints && SP.P.Tok.getText() == "no_existentials")
1155+
*perfConstraints = PerformanceConstraints::NoExistentials;
1156+
else if (perfConstraints && SP.P.Tok.getText() == "no_objc_bridging")
1157+
*perfConstraints = PerformanceConstraints::NoObjCBridging;
11521158
else if (markedAsUsed && SP.P.Tok.getText() == "used")
11531159
*markedAsUsed = true;
11541160
else if (section && SP.P.Tok.getText() == "section") {

lib/SIL/Utils/SILBridging.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ static_assert((int)BridgedFunction::EffectsKind::Custom == (int)swift::EffectsKi
212212
static_assert((int)BridgedFunction::PerformanceConstraints::None == (int)swift::PerformanceConstraints::None);
213213
static_assert((int)BridgedFunction::PerformanceConstraints::NoAllocation == (int)swift::PerformanceConstraints::NoAllocation);
214214
static_assert((int)BridgedFunction::PerformanceConstraints::NoLocks == (int)swift::PerformanceConstraints::NoLocks);
215+
static_assert((int)BridgedFunction::PerformanceConstraints::NoRuntime == (int)swift::PerformanceConstraints::NoRuntime);
216+
static_assert((int)BridgedFunction::PerformanceConstraints::NoExistentials == (int)swift::PerformanceConstraints::NoExistentials);
217+
static_assert((int)BridgedFunction::PerformanceConstraints::NoObjCBridging == (int)swift::PerformanceConstraints::NoObjCBridging);
215218

216219
static_assert((int)BridgedFunction::InlineStrategy::InlineDefault == (int)swift::InlineDefault);
217220
static_assert((int)BridgedFunction::InlineStrategy::NoInline == (int)swift::NoInline);

lib/SILOptimizer/Mandatory/PerformanceDiagnostics.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,28 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
388388
RuntimeEffect impact = getRuntimeEffect(inst, impactType);
389389
LocWithParent loc(inst->getLoc().getSourceLoc(), parentLoc);
390390

391+
if (perfConstr == PerformanceConstraints::NoExistentials &&
392+
(impact & RuntimeEffect::Existential)) {
393+
PrettyStackTracePerformanceDiagnostics stackTrace("existential", inst);
394+
if (impactType) {
395+
diagnose(loc, diag::perf_diag_existential_type, impactType.getASTType());
396+
} else {
397+
diagnose(loc, diag::perf_diag_existential);
398+
}
399+
return true;
400+
}
401+
402+
if ((perfConstr == PerformanceConstraints::NoObjCBridging ||
403+
perfConstr == PerformanceConstraints::NoAllocation ||
404+
perfConstr == PerformanceConstraints::NoLocks) &&
405+
(impact & RuntimeEffect::ObjectiveC)) {
406+
PrettyStackTracePerformanceDiagnostics stackTrace(
407+
"found objc effect", inst);
408+
409+
diagnose(loc, diag::performance_objectivec);
410+
return true;
411+
}
412+
391413
if (module.getOptions().EmbeddedSwift) {
392414
if (impact & RuntimeEffect::Existential) {
393415
PrettyStackTracePerformanceDiagnostics stackTrace("existential", inst);
@@ -412,7 +434,9 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
412434
}
413435
}
414436

415-
if (perfConstr == PerformanceConstraints::None)
437+
if (perfConstr == PerformanceConstraints::None ||
438+
perfConstr == PerformanceConstraints::NoExistentials ||
439+
perfConstr == PerformanceConstraints::NoObjCBridging)
416440
return false;
417441

418442
if (impact & RuntimeEffect::Casting) {
@@ -477,6 +501,10 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
477501
}
478502
return true;
479503
}
504+
505+
if (perfConstr == PerformanceConstraints::NoRuntime)
506+
return false;
507+
480508
if (impact & RuntimeEffect::Allocating) {
481509
PrettyStackTracePerformanceDiagnostics stackTrace(
482510
"found allocation effect", inst);
@@ -523,13 +551,6 @@ bool PerformanceDiagnostics::visitInst(SILInstruction *inst,
523551
diagnose(loc, diag::performance_deallocating, "this code pattern");
524552
return true;
525553
}
526-
if (impact & RuntimeEffect::ObjectiveC) {
527-
PrettyStackTracePerformanceDiagnostics stackTrace(
528-
"found objc effect", inst);
529-
530-
diagnose(loc, diag::performance_objectivec);
531-
return true;
532-
}
533554

534555
if (perfConstr == PerformanceConstraints::NoAllocation)
535556
return false;

0 commit comments

Comments
 (0)