1515#include " swift/SIL/SILArgument.h"
1616#include " swift/SIL/SILBasicBlock.h"
1717#include " swift/SIL/SILBridgingUtils.h"
18+ #include " swift/SIL/SILCloner.h"
1819#include " swift/SIL/SILFunction.h"
1920#include " swift/SIL/SILInstruction.h"
2021#include " swift/SIL/SILModule.h"
@@ -175,7 +176,7 @@ void SILFunction::init(SILLinkage Linkage, StringRef Name,
175176 IsDynamicallyReplaceable_t isDynamic,
176177 IsExactSelfClass_t isExactSelfClass,
177178 IsDistributed_t isDistributed) {
178- this -> Name = Name ;
179+ setName ( Name) ;
179180 this ->LoweredType = LoweredType;
180181 this ->GenericEnv = genericEnv;
181182 this ->SpecializationInfo = nullptr ;
@@ -215,6 +216,8 @@ SILFunction::~SILFunction() {
215216 // We also need to drop all references if instructions are allocated using
216217 // an allocator that may recycle freed memory.
217218 dropAllReferences ();
219+ if (snapshots)
220+ snapshots->~SILFunction ();
218221
219222 if (ReplacedFunction) {
220223 ReplacedFunction->decrementRefCount ();
@@ -237,6 +240,96 @@ SILFunction::~SILFunction() {
237240 destroyFunction ({this }, &libswiftSpecificData, sizeof (libswiftSpecificData));
238241}
239242
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+
240333void SILFunction::createProfiler (ASTNode Root, SILDeclRef forDecl,
241334 ForDefinition_t forDefinition) {
242335 assert (!Profiler && " Function already has a profiler" );
0 commit comments