Skip to content

Commit fea4a94

Browse files
authored
Merge pull request #60798 from eeckstein/swift-sil-fixes
Swift SIL: some small fixes
2 parents 9a4a21d + f7aaa35 commit fea4a94

File tree

9 files changed

+109
-48
lines changed

9 files changed

+109
-48
lines changed

SwiftCompilerSources/Sources/Optimizer/PassManager/PassContext.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,31 @@ extension Builder {
157157
self.init(insertAt: .before(insPnt), location: insPnt.location, passContext: context._bridged)
158158
}
159159

160-
/// Creates a builder which inserts _after_ `insPnt`, using the location of `insPnt`.
161-
init(after insPnt: Instruction, _ context: PassContext) {
160+
/// Creates a builder which inserts _after_ `insPnt`, using a custom `location`.
161+
init(after insPnt: Instruction, location: Location, _ context: PassContext) {
162162
if let nextInst = insPnt.next {
163-
self.init(insertAt: .before(nextInst), location: insPnt.location, passContext: context._bridged)
163+
self.init(insertAt: .before(nextInst), location: location, passContext: context._bridged)
164164
} else {
165-
self.init(insertAt: .atEndOf(insPnt.block), location: insPnt.location, passContext: context._bridged)
165+
self.init(insertAt: .atEndOf(insPnt.block), location: location, passContext: context._bridged)
166166
}
167167
}
168168

169+
/// Creates a builder which inserts _after_ `insPnt`, using the location of `insPnt`.
170+
init(after insPnt: Instruction, _ context: PassContext) {
171+
self.init(after: insPnt, location: insPnt.location, context)
172+
}
173+
169174
/// Creates a builder which inserts at the end of `block`, using a custom `location`.
170175
init(atEndOf block: BasicBlock, location: Location, _ context: PassContext) {
171176
self.init(insertAt: .atEndOf(block), location: location, passContext: context._bridged)
172177
}
173178

179+
/// Creates a builder which inserts at the begin of `block`, using a custom `location`.
180+
init(atBeginOf block: BasicBlock, location: Location, _ context: PassContext) {
181+
let firstInst = block.instructions.first!
182+
self.init(insertAt: .before(firstInst), location: location, passContext: context._bridged)
183+
}
184+
174185
/// Creates a builder which inserts at the begin of `block`, using the location of the first
175186
/// instruction of `block`.
176187
init(atBeginOf block: BasicBlock, _ context: PassContext) {

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,9 +480,8 @@ final public class RefTailAddrInst : SingleValueInstruction, UnaryInstruction {}
480480
final public class KeyPathInst : SingleValueInstruction {
481481
public override func visitReferencedFunctions(_ cl: (Function) -> ()) {
482482
var results = KeyPathFunctionResults()
483-
var componentIdx = 0
484-
repeat {
485-
componentIdx = KeyPathInst_getReferencedFunctions(bridged, componentIdx, &results)
483+
for componentIdx in 0..<KeyPathInst_getNumComponents(bridged) {
484+
KeyPathInst_getReferencedFunctions(bridged, componentIdx, &results)
486485
let numFuncs = results.numFunctions
487486
withUnsafePointer(to: &results) {
488487
$0.withMemoryRebound(to: BridgedFunction.self, capacity: numFuncs) {
@@ -492,7 +491,7 @@ final public class KeyPathInst : SingleValueInstruction {
492491
}
493492
}
494493
}
495-
} while componentIdx >= 0
494+
}
496495
}
497496
}
498497

SwiftCompilerSources/Sources/SIL/Location.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ import SILBridging
1414

1515
public struct Location {
1616
let bridged: BridgedLocation
17+
18+
public static var autoGeneratedLocation: Location {
19+
Location(bridged: SILLocation_getAutogeneratedLocation())
20+
}
1721
}

SwiftCompilerSources/Sources/SIL/WitnessTable.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public struct WitnessTable : CustomStringConvertible, CustomReflectable {
2121
fileprivate let bridged: BridgedWitnessTableEntry
2222

2323
public enum Kind {
24+
case invalid
2425
case method
2526
case associatedType
2627
case associatedTypeProtocol
@@ -29,6 +30,7 @@ public struct WitnessTable : CustomStringConvertible, CustomReflectable {
2930

3031
public var kind: Kind {
3132
switch SILWitnessTableEntry_getKind(bridged) {
33+
case SILWitnessTableEntry_Invalid: return .invalid
3234
case SILWitnessTableEntry_Method: return .method
3335
case SILWitnessTableEntry_AssociatedType: return .associatedType
3436
case SILWitnessTableEntry_AssociatedTypeProtocol: return .associatedTypeProtocol

include/swift/SIL/SILBridging.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef struct {
9999
} BridgedWitnessTableEntry;
100100

101101
typedef enum {
102+
SILWitnessTableEntry_Invalid,
102103
SILWitnessTableEntry_Method,
103104
SILWitnessTableEntry_AssociatedType,
104105
SILWitnessTableEntry_AssociatedTypeProtocol,
@@ -333,6 +334,8 @@ SwiftInt SILType_getCaseIdxOfEnumType(BridgedType type,
333334

334335
BridgedSubstitutionMap SubstitutionMap_getEmpty();
335336

337+
BridgedLocation SILLocation_getAutogeneratedLocation();
338+
336339
BridgedBasicBlock SILArgument_getParent(BridgedArgument argument);
337340
SwiftInt SILArgument_isExclusiveIndirectParameter(BridgedArgument argument);
338341

@@ -396,7 +399,8 @@ struct KeyPathFunctionResults {
396399
BridgedFunction functions[maxFunctions];
397400
SwiftInt numFunctions;
398401
};
399-
SwiftInt KeyPathInst_getReferencedFunctions(BridgedInstruction kpi, SwiftInt componentIdx,
402+
SwiftInt KeyPathInst_getNumComponents(BridgedInstruction kpi);
403+
void KeyPathInst_getReferencedFunctions(BridgedInstruction kpi, SwiftInt componentIdx,
400404
KeyPathFunctionResults * _Nonnull results);
401405

402406
BridgedSubstitutionMap ApplySite_getSubstitutionMap(BridgedInstruction inst);

include/swift/SILOptimizer/PassManager/PassManager.h

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ class SwiftPassInvocation {
6161
/// Non-null if this is an instruction pass, invoked from SILCombine.
6262
SILCombiner *silCombiner = nullptr;
6363

64+
/// Change notifications, collected during a pass run.
65+
SILAnalysis::InvalidationKind changeNotifications =
66+
SILAnalysis::InvalidationKind::Nothing;
67+
6468
/// All slabs, allocated by the pass.
6569
SILModule::SlabList allocatedSlabs;
6670

@@ -126,17 +130,9 @@ class SwiftPassInvocation {
126130
/// Called by the SILCombiner when the instruction pass has finished.
127131
void finishedInstructionPassRun();
128132

129-
void beginTransformFunction(SILFunction *function) {
130-
assert(!this->function && transform && "not running a module pass");
131-
this->function = function;
132-
}
133+
void beginTransformFunction(SILFunction *function);
133134

134-
void endTransformFunction() {
135-
assert(function && "beginTransformFunction not called");
136-
function = nullptr;
137-
assert(numBlockSetsAllocated == 0 && "Not all BasicBlockSets deallocated");
138-
assert(numNodeSetsAllocated == 0 && "Not all NodeSets deallocated");
139-
}
135+
void endTransformFunction();
140136
};
141137

142138
/// The SIL pass manager.
@@ -184,10 +180,6 @@ class SILPassManager {
184180
/// For invoking Swift passes.
185181
SwiftPassInvocation swiftPassInvocation;
186182

187-
/// Change notifications, collected during a bridged pass run.
188-
SILAnalysis::InvalidationKind changeNotifications =
189-
SILAnalysis::InvalidationKind::Nothing;
190-
191183
/// A mask which has one bit for each pass. A one for a pass-bit means that
192184
/// the pass doesn't need to run, because nothing has changed since the
193185
/// previous run of that pass.
@@ -341,11 +333,6 @@ class SILPassManager {
341333
CompletedPassesMap[F].reset();
342334
}
343335

344-
void notifyPassChanges(SILAnalysis::InvalidationKind invalidationKind) {
345-
changeNotifications = (SILAnalysis::InvalidationKind)
346-
(changeNotifications | invalidationKind);
347-
}
348-
349336
/// Reset the state of the pass manager and remove all transformation
350337
/// owned by the pass manager. Analysis passes will be kept.
351338
void resetAndRemoveTransformations();
@@ -440,7 +427,8 @@ class SILPassManager {
440427

441428
inline void SwiftPassInvocation::
442429
notifyChanges(SILAnalysis::InvalidationKind invalidationKind) {
443-
passManager->notifyPassChanges(invalidationKind);
430+
changeNotifications = (SILAnalysis::InvalidationKind)
431+
(changeNotifications | invalidationKind);
444432
}
445433

446434
} // end namespace swift

lib/SIL/Utils/SILBridging.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,15 @@ BridgedSubstitutionMap SubstitutionMap_getEmpty() {
529529
return {SubstitutionMap().getOpaqueValue()};
530530
}
531531

532+
//===----------------------------------------------------------------------===//
533+
// SILLocation
534+
//===----------------------------------------------------------------------===//
535+
536+
BridgedLocation SILLocation_getAutogeneratedLocation() {
537+
SILDebugLocation loc;
538+
return *reinterpret_cast<BridgedLocation *>(&loc);
539+
}
540+
532541
//===----------------------------------------------------------------------===//
533542
// SILGlobalVariable
534543
//===----------------------------------------------------------------------===//
@@ -625,6 +634,8 @@ std::string SILWitnessTableEntry_debugDescription(BridgedWitnessTableEntry entry
625634

626635
SILWitnessTableEntryKind SILWitnessTableEntry_getKind(BridgedWitnessTableEntry entry) {
627636
switch (castToWitnessTableEntry(entry)->getKind()) {
637+
case SILWitnessTable::Invalid:
638+
return SILWitnessTableEntry_Invalid;
628639
case SILWitnessTable::Method:
629640
return SILWitnessTableEntry_Method;
630641
case SILWitnessTable::AssociatedType:
@@ -633,8 +644,6 @@ SILWitnessTableEntryKind SILWitnessTableEntry_getKind(BridgedWitnessTableEntry e
633644
return SILWitnessTableEntry_AssociatedTypeProtocol;
634645
case SILWitnessTable::BaseProtocol:
635646
return SILWitnessTableEntry_BaseProtocol;
636-
default:
637-
llvm_unreachable("wrong witness table entry kind");
638647
}
639648
}
640649

@@ -877,7 +886,14 @@ SwiftInt CondBranchInst_getNumTrueArgs(BridgedInstruction cbr) {
877886
return castToInst<CondBranchInst>(cbr)->getNumTrueArgs();
878887
}
879888

880-
SwiftInt KeyPathInst_getReferencedFunctions(BridgedInstruction kpi, SwiftInt componentIdx,
889+
SwiftInt KeyPathInst_getNumComponents(BridgedInstruction kpi) {
890+
if (KeyPathPattern *pattern = castToInst<KeyPathInst>(kpi)->getPattern()) {
891+
return (SwiftInt)pattern->getComponents().size();
892+
}
893+
return 0;
894+
}
895+
896+
void KeyPathInst_getReferencedFunctions(BridgedInstruction kpi, SwiftInt componentIdx,
881897
KeyPathFunctionResults * _Nonnull results) {
882898
KeyPathPattern *pattern = castToInst<KeyPathInst>(kpi)->getPattern();
883899
const KeyPathPatternComponent &comp = pattern->getComponents()[componentIdx];
@@ -887,9 +903,6 @@ SwiftInt KeyPathInst_getReferencedFunctions(BridgedInstruction kpi, SwiftInt com
887903
assert(results->numFunctions < KeyPathFunctionResults::maxFunctions);
888904
results->functions[results->numFunctions++] = {func};
889905
}, [](SILDeclRef) {});
890-
891-
++componentIdx;
892-
return componentIdx < (int)pattern->getComponents().size() ? componentIdx : -1;
893906
}
894907

895908
BridgedSubstitutionMap ApplySite_getSubstitutionMap(BridgedInstruction inst) {

lib/SILOptimizer/PassManager/PassManager.cpp

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -530,9 +530,6 @@ void SILPassManager::runPassOnFunction(unsigned TransIdx, SILFunction *F) {
530530
forcePrecomputeAnalyses(F);
531531
}
532532

533-
assert(changeNotifications == SILAnalysis::InvalidationKind::Nothing
534-
&& "change notifications not cleared");
535-
536533
llvm::sys::TimePoint<> startTime = std::chrono::system_clock::now();
537534
std::chrono::nanoseconds duration(0);
538535

@@ -553,24 +550,21 @@ void SILPassManager::runPassOnFunction(unsigned TransIdx, SILFunction *F) {
553550
// Run it!
554551
SFT->run();
555552

556-
if (CurrentPassHasInvalidated ||
557-
changeNotifications != SILAnalysis::InvalidationKind::Nothing) {
553+
swiftPassInvocation.finishedFunctionPassRun();
554+
555+
if (CurrentPassHasInvalidated) {
558556
// Pause time measurement while invalidating analysis and restoring the snapshot.
559557
duration += (std::chrono::system_clock::now() - startTime);
560558

561559
if (runIdx < numRepeats - 1) {
562560
invalidateAnalysis(F, SILAnalysis::InvalidationKind::Everything);
563561
F->restoreFromSnapshot(SnapshotID);
564-
} else if (changeNotifications != SILAnalysis::InvalidationKind::Nothing) {
565-
invalidateAnalysis(F, changeNotifications);
566562
}
567-
changeNotifications = SILAnalysis::InvalidationKind::Nothing;
568563

569564
// Continue time measurement (including flushing deleted instructions).
570565
startTime = std::chrono::system_clock::now();
571566
}
572567
Mod->flushDeletedInsts();
573-
swiftPassInvocation.finishedFunctionPassRun();
574568
}
575569

576570
duration += (std::chrono::system_clock::now() - startTime);
@@ -1289,9 +1283,9 @@ void SwiftPassInvocation::startModulePassRun(SILModuleTransform *transform) {
12891283
}
12901284

12911285
void SwiftPassInvocation::startFunctionPassRun(SILFunctionTransform *transform) {
1292-
assert(!this->function && !this->transform && "a pass is already running");
1293-
this->function = transform->getFunction();
1286+
assert(!this->transform && "a pass is already running");
12941287
this->transform = transform;
1288+
beginTransformFunction(transform->getFunction());
12951289
}
12961290

12971291
void SwiftPassInvocation::startInstructionPassRun(SILInstruction *inst) {
@@ -1302,13 +1296,15 @@ void SwiftPassInvocation::startInstructionPassRun(SILInstruction *inst) {
13021296
void SwiftPassInvocation::finishedModulePassRun() {
13031297
endPassRunChecks();
13041298
assert(!function && transform && "not running a pass");
1299+
assert(changeNotifications == SILAnalysis::InvalidationKind::Nothing
1300+
&& "unhandled change notifications at end of module pass");
13051301
transform = nullptr;
13061302
}
13071303

13081304
void SwiftPassInvocation::finishedFunctionPassRun() {
13091305
endPassRunChecks();
1310-
assert(function && transform && "not running a pass");
1311-
function = nullptr;
1306+
endTransformFunction();
1307+
assert(allocatedSlabs.empty() && "StackList is leaking slabs");
13121308
transform = nullptr;
13131309
}
13141310

@@ -1322,6 +1318,24 @@ void SwiftPassInvocation::endPassRunChecks() {
13221318
assert(numNodeSetsAllocated == 0 && "Not all NodeSets deallocated");
13231319
}
13241320

1321+
void SwiftPassInvocation::beginTransformFunction(SILFunction *function) {
1322+
assert(!this->function && transform && "not running a pass");
1323+
assert(changeNotifications == SILAnalysis::InvalidationKind::Nothing
1324+
&& "change notifications not cleared");
1325+
this->function = function;
1326+
}
1327+
1328+
void SwiftPassInvocation::endTransformFunction() {
1329+
assert(function && transform && "not running a pass");
1330+
if (changeNotifications != SILAnalysis::InvalidationKind::Nothing) {
1331+
passManager->invalidateAnalysis(function, changeNotifications);
1332+
changeNotifications = SILAnalysis::InvalidationKind::Nothing;
1333+
}
1334+
function = nullptr;
1335+
assert(numBlockSetsAllocated == 0 && "Not all BasicBlockSets deallocated");
1336+
assert(numNodeSetsAllocated == 0 && "Not all NodeSets deallocated");
1337+
}
1338+
13251339
//===----------------------------------------------------------------------===//
13261340
// Swift Bridging
13271341
//===----------------------------------------------------------------------===//

test/SILOptimizer/function_uses.sil

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,26 @@ sil_default_witness_table RP {
153153
method #RP.default_witness: @default_witness
154154
}
155155

156+
public protocol RP2 {
157+
}
158+
159+
sil_default_witness_table RP2 {
160+
no_default
161+
}
162+
156163
protocol P {
157164
func witness()
165+
func witness2()
158166
}
159167

160168
struct SP : P {
161169
func witness()
170+
func witness2()
171+
}
172+
173+
struct SP2 : P {
174+
func witness()
175+
func witness2()
162176
}
163177

164178
// CHECK-LABEL: Uses of witness
@@ -172,8 +186,20 @@ bb0(%0 : $*SP):
172186
return %7 : $()
173187
}
174188

189+
sil @witness2 : $@convention(witness_method: P) (@inout SP) -> () {
190+
bb0(%0 : $*SP):
191+
%7 = tuple ()
192+
return %7 : $()
193+
}
194+
175195
sil_witness_table SP: P module witness_tables {
176196
method #P.witness: @witness
197+
method #P.witness2: @witness2
198+
}
199+
200+
sil_witness_table SP2: P module witness_tables {
201+
method #P.witness: @witness
202+
method #P.witness2: @witness2
177203
}
178204

179205
// CHECK-LABEL: Uses of hash_func

0 commit comments

Comments
 (0)