15
15
#include " swift/SIL/SILArgument.h"
16
16
#include " swift/SIL/SILBasicBlock.h"
17
17
#include " swift/SIL/SILBridgingUtils.h"
18
+ #include " swift/SIL/SILCloner.h"
18
19
#include " swift/SIL/SILFunction.h"
19
20
#include " swift/SIL/SILInstruction.h"
20
21
#include " swift/SIL/SILModule.h"
@@ -175,7 +176,7 @@ void SILFunction::init(SILLinkage Linkage, StringRef Name,
175
176
IsDynamicallyReplaceable_t isDynamic,
176
177
IsExactSelfClass_t isExactSelfClass,
177
178
IsDistributed_t isDistributed) {
178
- this -> Name = Name ;
179
+ setName ( Name) ;
179
180
this ->LoweredType = LoweredType;
180
181
this ->GenericEnv = genericEnv;
181
182
this ->SpecializationInfo = nullptr ;
@@ -215,6 +216,8 @@ SILFunction::~SILFunction() {
215
216
// We also need to drop all references if instructions are allocated using
216
217
// an allocator that may recycle freed memory.
217
218
dropAllReferences ();
219
+ if (snapshots)
220
+ snapshots->~SILFunction ();
218
221
219
222
if (ReplacedFunction) {
220
223
ReplacedFunction->decrementRefCount ();
@@ -237,6 +240,96 @@ SILFunction::~SILFunction() {
237
240
destroyFunction ({this }, &libswiftSpecificData, sizeof (libswiftSpecificData));
238
241
}
239
242
243
+ void SILFunction::createSnapshot (int id) {
244
+ assert (id != 0 && " invalid snapshot ID" );
245
+ assert (!getSnapshot (id) && " duplicate snapshot" );
246
+
247
+ SILFunction *newSnapshot = new (Module) SILFunction (Module,
248
+ getLinkage (), getName (), getLoweredFunctionType (), getGenericEnvironment (),
249
+ getLocation (), isBare (), isTransparent (), isSerialized (),
250
+ getEntryCount (), isThunk (), getClassSubclassScope (),
251
+ getInlineStrategy (), getEffectsKind (), getDebugScope (),
252
+ isDynamicallyReplaceable (), isExactSelfClass (), isDistributed ());
253
+
254
+ // Copy all relevant properties.
255
+ // TODO: It's really unfortunate that this needs to be done manually. It would
256
+ // be nice if all the properties are encapsulated into a single state,
257
+ // which can be copied at once.
258
+ newSnapshot->SpecializationInfo = SpecializationInfo;
259
+ newSnapshot->ClangNodeOwner = ClangNodeOwner;
260
+ newSnapshot->DeclCtxt = DeclCtxt;
261
+ newSnapshot->Profiler = Profiler;
262
+ newSnapshot->ReplacedFunction = ReplacedFunction;
263
+ newSnapshot->RefAdHocRequirementFunction = RefAdHocRequirementFunction;
264
+ newSnapshot->ObjCReplacementFor = ObjCReplacementFor;
265
+ newSnapshot->SemanticsAttrSet = SemanticsAttrSet;
266
+ newSnapshot->SpecializeAttrSet = SpecializeAttrSet;
267
+ newSnapshot->Availability = Availability;
268
+ newSnapshot->specialPurpose = specialPurpose;
269
+ newSnapshot->perfConstraints = perfConstraints;
270
+ newSnapshot->GlobalInitFlag = GlobalInitFlag;
271
+ newSnapshot->HasCReferences = HasCReferences;
272
+ newSnapshot->IsWeakImported = IsWeakImported;
273
+ newSnapshot->HasOwnership = HasOwnership;
274
+ newSnapshot->IsWithoutActuallyEscapingThunk = IsWithoutActuallyEscapingThunk;
275
+ newSnapshot->OptMode = OptMode;
276
+ newSnapshot->IsStaticallyLinked = IsStaticallyLinked;
277
+ newSnapshot->copyEffects (this );
278
+
279
+ SILFunctionCloner cloner (newSnapshot);
280
+ cloner.cloneFunction (this );
281
+
282
+ newSnapshot->snapshotID = id;
283
+ newSnapshot->snapshots = this ->snapshots ;
284
+ this ->snapshots = newSnapshot;
285
+
286
+ // The cloner sometimes removes temporary instructions.
287
+ getModule ().flushDeletedInsts ();
288
+ }
289
+
290
+ SILFunction *SILFunction::getSnapshot (int ID) {
291
+ SILFunction *sn = this ;
292
+ do {
293
+ if (sn->snapshotID == ID)
294
+ return sn;
295
+ sn = sn->snapshots ;
296
+ } while (sn);
297
+ return nullptr ;
298
+ }
299
+
300
+ void SILFunction::restoreFromSnapshot (int ID) {
301
+ SILFunction *sn = getSnapshot (ID);
302
+ assert (sn && " no snapshot found" );
303
+
304
+ clear ();
305
+ SILFunctionCloner cloner (this );
306
+ cloner.cloneFunction (sn);
307
+
308
+ // Beside the function body, only restore those properties, which are/can be
309
+ // modified by passes.
310
+ // TODO: There should be a clear sepratation from initialize-once properties
311
+ // (`let`) and properties which can be modified by passes (`var`).
312
+ copyEffects (sn);
313
+
314
+ // The cloner sometimes removes temporary instructions.
315
+ getModule ().flushDeletedInsts ();
316
+ }
317
+
318
+ void SILFunction::deleteSnapshot (int ID) {
319
+ SILFunction *f = this ;
320
+ do {
321
+ if (SILFunction *sn = f->snapshots ) {
322
+ if (sn->snapshotID == ID) {
323
+ f->snapshots = sn->snapshots ;
324
+ sn->snapshots = nullptr ;
325
+ sn->~SILFunction ();
326
+ getModule ().flushDeletedInsts ();
327
+ return ;
328
+ }
329
+ }
330
+ } while ((f = f->snapshots ) != nullptr );
331
+ }
332
+
240
333
void SILFunction::createProfiler (ASTNode Root, SILDeclRef forDecl,
241
334
ForDefinition_t forDefinition) {
242
335
assert (!Profiler && " Function already has a profiler" );
0 commit comments